@plasius/economy 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/dist/index.cjs +650 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +167 -5
- package/dist/index.d.ts +167 -5
- package/dist/index.js +635 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -100,9 +100,16 @@ __export(index_exports, {
|
|
|
100
100
|
assertModuleSpendQuote: () => assertModuleSpendQuote,
|
|
101
101
|
assertNonNegativeAccounts: () => assertNonNegativeAccounts,
|
|
102
102
|
assertOpenPurchaseIntent: () => assertOpenPurchaseIntent,
|
|
103
|
+
assertOperatorAdjustmentDecision: () => assertOperatorAdjustmentDecision,
|
|
104
|
+
assertOperatorAdjustmentExecution: () => assertOperatorAdjustmentExecution,
|
|
105
|
+
assertOperatorAdjustmentPreview: () => assertOperatorAdjustmentPreview,
|
|
106
|
+
assertOperatorAdjustmentProposal: () => assertOperatorAdjustmentProposal,
|
|
103
107
|
assertPaidLotLifecycle: () => assertPaidLotLifecycle,
|
|
104
108
|
assertPaidLotLifecycleEvent: () => assertPaidLotLifecycleEvent,
|
|
105
109
|
assertPaidLotPurchaseProvenance: () => assertPaidLotPurchaseProvenance,
|
|
110
|
+
assertPersonalWalletInitializationCommand: () => assertPersonalWalletInitializationCommand,
|
|
111
|
+
assertPersonalWalletInitializationOutboxIntent: () => assertPersonalWalletInitializationOutboxIntent,
|
|
112
|
+
assertPersonalWalletInitializationState: () => assertPersonalWalletInitializationState,
|
|
106
113
|
assertPurchaseCapReservation: () => assertPurchaseCapReservation,
|
|
107
114
|
assertPurchaseCapReservationTransition: () => assertPurchaseCapReservationTransition,
|
|
108
115
|
assertPurchaseIntentBinding: () => assertPurchaseIntentBinding,
|
|
@@ -160,6 +167,12 @@ __export(index_exports, {
|
|
|
160
167
|
canonicalEconomyRegionalEvidenceReceiptBodyPayload: () => canonicalEconomyRegionalEvidenceReceiptBodyPayload,
|
|
161
168
|
canonicalEconomyRegionalEvidenceReceiptPayload: () => canonicalEconomyRegionalEvidenceReceiptPayload,
|
|
162
169
|
canonicalEconomyRegionalEvidenceReceiptSigningPayload: () => canonicalEconomyRegionalEvidenceReceiptSigningPayload,
|
|
170
|
+
canonicalOperatorAdjustmentDecisionPayload: () => canonicalOperatorAdjustmentDecisionPayload,
|
|
171
|
+
canonicalOperatorAdjustmentExecutionPayload: () => canonicalOperatorAdjustmentExecutionPayload,
|
|
172
|
+
canonicalOperatorAdjustmentPreviewPayload: () => canonicalOperatorAdjustmentPreviewPayload,
|
|
173
|
+
canonicalOperatorAdjustmentProposalPayload: () => canonicalOperatorAdjustmentProposalPayload,
|
|
174
|
+
canonicalPersonalWalletInitializationCommandPayload: () => canonicalPersonalWalletInitializationCommandPayload,
|
|
175
|
+
canonicalPersonalWalletInitializationOutboxPayload: () => canonicalPersonalWalletInitializationOutboxPayload,
|
|
163
176
|
canonicalTransactionPayload: () => canonicalTransactionPayload,
|
|
164
177
|
closeModuleAllowance: () => closeModuleAllowance,
|
|
165
178
|
convertRewardPayout: () => convertRewardPayout,
|
|
@@ -175,6 +188,8 @@ __export(index_exports, {
|
|
|
175
188
|
createModuleSpendHold: () => createModuleSpendHold,
|
|
176
189
|
createModuleSpendQuote: () => createModuleSpendQuote,
|
|
177
190
|
createPaidLotLifecycle: () => createPaidLotLifecycle,
|
|
191
|
+
createPersonalWalletInitializationDocumentIds: () => createPersonalWalletInitializationDocumentIds,
|
|
192
|
+
createPersonalWalletInitializationState: () => createPersonalWalletInitializationState,
|
|
178
193
|
createProjectionSnapshot: () => createProjectionSnapshot,
|
|
179
194
|
createPurchaseIntentLifecycle: () => createPurchaseIntentLifecycle,
|
|
180
195
|
createReversalTransaction: () => createReversalTransaction,
|
|
@@ -965,7 +980,8 @@ var COMMAND_TYPES = /* @__PURE__ */ new Set([
|
|
|
965
980
|
"refund",
|
|
966
981
|
"chargeback",
|
|
967
982
|
"reverse",
|
|
968
|
-
"adjust"
|
|
983
|
+
"adjust",
|
|
984
|
+
"initialize-wallet"
|
|
969
985
|
]);
|
|
970
986
|
var COMMAND_SOURCES = /* @__PURE__ */ new Set([
|
|
971
987
|
"browser",
|
|
@@ -1012,7 +1028,8 @@ var SOURCE_COMMAND_TYPES = {
|
|
|
1012
1028
|
"reclaim",
|
|
1013
1029
|
"spend",
|
|
1014
1030
|
"hold",
|
|
1015
|
-
"release-hold"
|
|
1031
|
+
"release-hold",
|
|
1032
|
+
"initialize-wallet"
|
|
1016
1033
|
]),
|
|
1017
1034
|
shopify: /* @__PURE__ */ new Set([
|
|
1018
1035
|
"credit-purchase",
|
|
@@ -1207,6 +1224,13 @@ function assertCommandSourcePrincipal(envelope) {
|
|
|
1207
1224
|
"Delegated-child commands require a distinct actor and relationship"
|
|
1208
1225
|
);
|
|
1209
1226
|
}
|
|
1227
|
+
if (envelope.commandType === "initialize-wallet") {
|
|
1228
|
+
economyAssert(
|
|
1229
|
+
envelope.commandSource === "browser" && envelope.principalType === "account" && envelope.actorAccountId === envelope.subjectAccountId && envelope.relationshipId === void 0 && envelope.authorizationVersion === void 0,
|
|
1230
|
+
"INVALID_CONTRACT",
|
|
1231
|
+
"Wallet initialization requires a direct self-account browser command"
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1210
1234
|
}
|
|
1211
1235
|
function assertAuditedEconomyCommandEnvelope(envelope) {
|
|
1212
1236
|
assertExactKeys(
|
|
@@ -1808,6 +1832,7 @@ var RECORD_KINDS = /* @__PURE__ */ new Set([
|
|
|
1808
1832
|
"source-lot",
|
|
1809
1833
|
"source-lot-movement",
|
|
1810
1834
|
"gameplay-allocation",
|
|
1835
|
+
"wallet",
|
|
1811
1836
|
"balance-projection",
|
|
1812
1837
|
"lifetime-projection",
|
|
1813
1838
|
"idempotency-result",
|
|
@@ -2995,6 +3020,13 @@ function assertReceiptGraph(graph, commandEnvelopeHash, hash, acceptanceCommit,
|
|
|
2995
3020
|
result.receiptId,
|
|
2996
3021
|
resultHash
|
|
2997
3022
|
);
|
|
3023
|
+
if (envelope.commandType === "initialize-wallet") {
|
|
3024
|
+
economyAssert(
|
|
3025
|
+
result.outcome === "no-op" && (result.noOpCode === "WALLET_INITIALIZED" || result.noOpCode === "WALLET_ALREADY_INITIALIZED"),
|
|
3026
|
+
"INVALID_CONTRACT",
|
|
3027
|
+
"Wallet initialization must terminate without an economic transaction"
|
|
3028
|
+
);
|
|
3029
|
+
}
|
|
2998
3030
|
if (result.outcome !== "completed") {
|
|
2999
3031
|
economyAssert(
|
|
3000
3032
|
graph.transaction === void 0,
|
|
@@ -4522,6 +4554,341 @@ function assertDistinctAdjustmentApproval(request) {
|
|
|
4522
4554
|
}
|
|
4523
4555
|
}
|
|
4524
4556
|
|
|
4557
|
+
// src/operator-adjustments.ts
|
|
4558
|
+
var PREVIEW_KEYS = /* @__PURE__ */ new Set([
|
|
4559
|
+
"schemaVersion",
|
|
4560
|
+
"previewId",
|
|
4561
|
+
"adjustmentId",
|
|
4562
|
+
"operation",
|
|
4563
|
+
"targetAccountId",
|
|
4564
|
+
"targetComponent",
|
|
4565
|
+
"targetWalletId",
|
|
4566
|
+
"targetLedgerAccountId",
|
|
4567
|
+
"offsetLedgerAccountId",
|
|
4568
|
+
"sourceLotId",
|
|
4569
|
+
"amount",
|
|
4570
|
+
"reasonCode",
|
|
4571
|
+
"ticketReferenceHash",
|
|
4572
|
+
"transferPolicy",
|
|
4573
|
+
"refundPolicy",
|
|
4574
|
+
"originalSourceLotId",
|
|
4575
|
+
"originalTransactionId",
|
|
4576
|
+
"preparedAt",
|
|
4577
|
+
"expiresAt"
|
|
4578
|
+
]);
|
|
4579
|
+
var DECISION_KEYS = /* @__PURE__ */ new Set([
|
|
4580
|
+
"schemaVersion",
|
|
4581
|
+
"decisionId",
|
|
4582
|
+
"adjustmentId",
|
|
4583
|
+
"proposalId",
|
|
4584
|
+
"proposalHash",
|
|
4585
|
+
"previewHash",
|
|
4586
|
+
"decision",
|
|
4587
|
+
"proposedByAccountId",
|
|
4588
|
+
"decidedByAccountId",
|
|
4589
|
+
"proposedAt",
|
|
4590
|
+
"decidedAt"
|
|
4591
|
+
]);
|
|
4592
|
+
var PROPOSAL_KEYS = /* @__PURE__ */ new Set([
|
|
4593
|
+
"schemaVersion",
|
|
4594
|
+
"proposalId",
|
|
4595
|
+
"adjustmentId",
|
|
4596
|
+
"previewHash",
|
|
4597
|
+
"status",
|
|
4598
|
+
"proposedByAccountId",
|
|
4599
|
+
"proposedAt",
|
|
4600
|
+
"expiresAt"
|
|
4601
|
+
]);
|
|
4602
|
+
var EXECUTION_KEYS = /* @__PURE__ */ new Set([
|
|
4603
|
+
"schemaVersion",
|
|
4604
|
+
"executionId",
|
|
4605
|
+
"adjustmentId",
|
|
4606
|
+
"previewHash",
|
|
4607
|
+
"proposalHash",
|
|
4608
|
+
"decisionHash",
|
|
4609
|
+
"sourceLotId",
|
|
4610
|
+
"transactionId",
|
|
4611
|
+
"resultReceiptId",
|
|
4612
|
+
"executedAt"
|
|
4613
|
+
]);
|
|
4614
|
+
var OPERATIONS = /* @__PURE__ */ new Set([
|
|
4615
|
+
"credit",
|
|
4616
|
+
"reverse-credit"
|
|
4617
|
+
]);
|
|
4618
|
+
var TARGET_COMPONENTS = /* @__PURE__ */ new Set([
|
|
4619
|
+
"personal",
|
|
4620
|
+
"household-treasury"
|
|
4621
|
+
]);
|
|
4622
|
+
var TRANSFER_POLICIES = /* @__PURE__ */ new Set([
|
|
4623
|
+
"household-allocatable",
|
|
4624
|
+
"same-user-only",
|
|
4625
|
+
"non-transferable"
|
|
4626
|
+
]);
|
|
4627
|
+
var DECISIONS = /* @__PURE__ */ new Set([
|
|
4628
|
+
"approve",
|
|
4629
|
+
"reject"
|
|
4630
|
+
]);
|
|
4631
|
+
function assertExactKeys3(value, allowed, label) {
|
|
4632
|
+
economyAssert(
|
|
4633
|
+
value !== null && typeof value === "object" && !Array.isArray(value),
|
|
4634
|
+
"INVALID_CONTRACT",
|
|
4635
|
+
`${label} must be an object`
|
|
4636
|
+
);
|
|
4637
|
+
economyAssert(
|
|
4638
|
+
Object.keys(value).every((key) => allowed.has(key)),
|
|
4639
|
+
"INVALID_CONTRACT",
|
|
4640
|
+
`${label} contains an unsupported field`
|
|
4641
|
+
);
|
|
4642
|
+
}
|
|
4643
|
+
function assertCanonicalHash6(value, label) {
|
|
4644
|
+
economyAssert(
|
|
4645
|
+
/^sha256:[a-f0-9]{64}$/u.test(value),
|
|
4646
|
+
"INVALID_CONTRACT",
|
|
4647
|
+
`${label} must be a canonical SHA-256 reference`
|
|
4648
|
+
);
|
|
4649
|
+
}
|
|
4650
|
+
function assertReasonCode(reasonCode) {
|
|
4651
|
+
economyAssert(
|
|
4652
|
+
/^[A-Z][A-Z0-9_]{2,95}$/u.test(reasonCode),
|
|
4653
|
+
"INVALID_CONTRACT",
|
|
4654
|
+
"Adjustment reasonCode must be a bounded uppercase identifier"
|
|
4655
|
+
);
|
|
4656
|
+
}
|
|
4657
|
+
function assertOperatorAdjustmentPreview(preview) {
|
|
4658
|
+
assertExactKeys3(preview, PREVIEW_KEYS, "Operator adjustment preview");
|
|
4659
|
+
economyAssert(
|
|
4660
|
+
preview.schemaVersion === ECONOMY_CONTRACT_VERSION && OPERATIONS.has(preview.operation) && TARGET_COMPONENTS.has(preview.targetComponent) && TRANSFER_POLICIES.has(preview.transferPolicy) && preview.refundPolicy === "not-refundable",
|
|
4661
|
+
"INVALID_CONTRACT",
|
|
4662
|
+
"Unsupported operator adjustment preview"
|
|
4663
|
+
);
|
|
4664
|
+
assertEconomyIdentifier(preview.previewId, "previewId");
|
|
4665
|
+
assertEconomyIdentifier(preview.adjustmentId, "adjustmentId");
|
|
4666
|
+
assertEconomyIdentifier(preview.targetAccountId, "targetAccountId");
|
|
4667
|
+
assertEconomyIdentifier(preview.targetWalletId, "targetWalletId");
|
|
4668
|
+
assertEconomyIdentifier(
|
|
4669
|
+
preview.targetLedgerAccountId,
|
|
4670
|
+
"targetLedgerAccountId"
|
|
4671
|
+
);
|
|
4672
|
+
assertEconomyIdentifier(
|
|
4673
|
+
preview.offsetLedgerAccountId,
|
|
4674
|
+
"offsetLedgerAccountId"
|
|
4675
|
+
);
|
|
4676
|
+
assertEconomyIdentifier(preview.sourceLotId, "sourceLotId");
|
|
4677
|
+
economyAssert(
|
|
4678
|
+
parseTokenSubunits(preview.amount) > 0n,
|
|
4679
|
+
"INVALID_AMOUNT",
|
|
4680
|
+
"Operator adjustment amount must be positive"
|
|
4681
|
+
);
|
|
4682
|
+
assertReasonCode(preview.reasonCode);
|
|
4683
|
+
assertCanonicalHash6(preview.ticketReferenceHash, "ticketReferenceHash");
|
|
4684
|
+
const preparedAt = parseIsoTimestamp(preview.preparedAt);
|
|
4685
|
+
const expiresAt = parseIsoTimestamp(preview.expiresAt);
|
|
4686
|
+
economyAssert(
|
|
4687
|
+
expiresAt > preparedAt,
|
|
4688
|
+
"INVALID_TIME_WINDOW",
|
|
4689
|
+
"Operator adjustment preview must expire after preparation"
|
|
4690
|
+
);
|
|
4691
|
+
if (preview.operation === "credit") {
|
|
4692
|
+
economyAssert(
|
|
4693
|
+
preview.originalSourceLotId === void 0 && preview.originalTransactionId === void 0,
|
|
4694
|
+
"INVALID_CONTRACT",
|
|
4695
|
+
"A credit preview cannot bind an original transaction"
|
|
4696
|
+
);
|
|
4697
|
+
return;
|
|
4698
|
+
}
|
|
4699
|
+
economyAssert(
|
|
4700
|
+
preview.originalSourceLotId !== void 0 && preview.originalTransactionId !== void 0,
|
|
4701
|
+
"INVALID_CONTRACT",
|
|
4702
|
+
"A reversal preview must bind the original lot and transaction"
|
|
4703
|
+
);
|
|
4704
|
+
assertEconomyIdentifier(preview.originalSourceLotId, "originalSourceLotId");
|
|
4705
|
+
assertEconomyIdentifier(
|
|
4706
|
+
preview.originalTransactionId,
|
|
4707
|
+
"originalTransactionId"
|
|
4708
|
+
);
|
|
4709
|
+
}
|
|
4710
|
+
function canonicalOperatorAdjustmentPreviewPayload(preview) {
|
|
4711
|
+
assertOperatorAdjustmentPreview(preview);
|
|
4712
|
+
return JSON.stringify({
|
|
4713
|
+
schemaVersion: preview.schemaVersion,
|
|
4714
|
+
previewId: preview.previewId,
|
|
4715
|
+
adjustmentId: preview.adjustmentId,
|
|
4716
|
+
operation: preview.operation,
|
|
4717
|
+
targetAccountId: preview.targetAccountId,
|
|
4718
|
+
targetComponent: preview.targetComponent,
|
|
4719
|
+
targetWalletId: preview.targetWalletId,
|
|
4720
|
+
targetLedgerAccountId: preview.targetLedgerAccountId,
|
|
4721
|
+
offsetLedgerAccountId: preview.offsetLedgerAccountId,
|
|
4722
|
+
sourceLotId: preview.sourceLotId,
|
|
4723
|
+
amount: preview.amount,
|
|
4724
|
+
reasonCode: preview.reasonCode,
|
|
4725
|
+
ticketReferenceHash: preview.ticketReferenceHash,
|
|
4726
|
+
transferPolicy: preview.transferPolicy,
|
|
4727
|
+
refundPolicy: preview.refundPolicy,
|
|
4728
|
+
...preview.originalSourceLotId === void 0 ? {} : { originalSourceLotId: preview.originalSourceLotId },
|
|
4729
|
+
...preview.originalTransactionId === void 0 ? {} : { originalTransactionId: preview.originalTransactionId },
|
|
4730
|
+
preparedAt: preview.preparedAt,
|
|
4731
|
+
expiresAt: preview.expiresAt
|
|
4732
|
+
});
|
|
4733
|
+
}
|
|
4734
|
+
function assertOperatorAdjustmentProposal(proposal, preview, expectedPreviewHash) {
|
|
4735
|
+
assertOperatorAdjustmentPreview(preview);
|
|
4736
|
+
assertCanonicalHash6(expectedPreviewHash, "expectedPreviewHash");
|
|
4737
|
+
assertExactKeys3(proposal, PROPOSAL_KEYS, "Operator adjustment proposal");
|
|
4738
|
+
economyAssert(
|
|
4739
|
+
proposal.schemaVersion === ECONOMY_CONTRACT_VERSION && proposal.status === "pending-approval",
|
|
4740
|
+
"INVALID_CONTRACT",
|
|
4741
|
+
"Unsupported operator adjustment proposal"
|
|
4742
|
+
);
|
|
4743
|
+
assertEconomyIdentifier(proposal.proposalId, "proposalId");
|
|
4744
|
+
assertEconomyIdentifier(proposal.adjustmentId, "adjustmentId");
|
|
4745
|
+
assertCanonicalHash6(proposal.previewHash, "previewHash");
|
|
4746
|
+
assertEconomyIdentifier(
|
|
4747
|
+
proposal.proposedByAccountId,
|
|
4748
|
+
"proposedByAccountId"
|
|
4749
|
+
);
|
|
4750
|
+
economyAssert(
|
|
4751
|
+
proposal.adjustmentId === preview.adjustmentId && proposal.previewHash === expectedPreviewHash,
|
|
4752
|
+
"ADJUSTMENT_PREVIEW_MISMATCH",
|
|
4753
|
+
"Operator adjustment proposal does not match its preview"
|
|
4754
|
+
);
|
|
4755
|
+
const proposedAt = parseIsoTimestamp(proposal.proposedAt);
|
|
4756
|
+
const expiresAt = parseIsoTimestamp(proposal.expiresAt);
|
|
4757
|
+
economyAssert(
|
|
4758
|
+
proposedAt >= parseIsoTimestamp(preview.preparedAt) && expiresAt === parseIsoTimestamp(preview.expiresAt) && expiresAt > proposedAt,
|
|
4759
|
+
"INVALID_TIME_WINDOW",
|
|
4760
|
+
"Operator adjustment proposal times are inconsistent"
|
|
4761
|
+
);
|
|
4762
|
+
}
|
|
4763
|
+
function canonicalOperatorAdjustmentProposalPayload(proposal) {
|
|
4764
|
+
assertExactKeys3(proposal, PROPOSAL_KEYS, "Operator adjustment proposal");
|
|
4765
|
+
return JSON.stringify({
|
|
4766
|
+
schemaVersion: proposal.schemaVersion,
|
|
4767
|
+
proposalId: proposal.proposalId,
|
|
4768
|
+
adjustmentId: proposal.adjustmentId,
|
|
4769
|
+
previewHash: proposal.previewHash,
|
|
4770
|
+
status: proposal.status,
|
|
4771
|
+
proposedByAccountId: proposal.proposedByAccountId,
|
|
4772
|
+
proposedAt: proposal.proposedAt,
|
|
4773
|
+
expiresAt: proposal.expiresAt
|
|
4774
|
+
});
|
|
4775
|
+
}
|
|
4776
|
+
function assertOperatorAdjustmentDecision(decision, proposal, preview, expectedPreviewHash, expectedProposalHash) {
|
|
4777
|
+
assertOperatorAdjustmentProposal(proposal, preview, expectedPreviewHash);
|
|
4778
|
+
assertCanonicalHash6(expectedProposalHash, "expectedProposalHash");
|
|
4779
|
+
assertExactKeys3(decision, DECISION_KEYS, "Operator adjustment decision");
|
|
4780
|
+
economyAssert(
|
|
4781
|
+
decision.schemaVersion === ECONOMY_CONTRACT_VERSION && DECISIONS.has(decision.decision),
|
|
4782
|
+
"INVALID_CONTRACT",
|
|
4783
|
+
"Unsupported operator adjustment decision"
|
|
4784
|
+
);
|
|
4785
|
+
assertEconomyIdentifier(decision.decisionId, "decisionId");
|
|
4786
|
+
assertEconomyIdentifier(decision.adjustmentId, "adjustmentId");
|
|
4787
|
+
assertEconomyIdentifier(decision.proposalId, "proposalId");
|
|
4788
|
+
assertCanonicalHash6(decision.proposalHash, "proposalHash");
|
|
4789
|
+
assertCanonicalHash6(decision.previewHash, "previewHash");
|
|
4790
|
+
assertEconomyIdentifier(
|
|
4791
|
+
decision.proposedByAccountId,
|
|
4792
|
+
"proposedByAccountId"
|
|
4793
|
+
);
|
|
4794
|
+
assertEconomyIdentifier(
|
|
4795
|
+
decision.decidedByAccountId,
|
|
4796
|
+
"decidedByAccountId"
|
|
4797
|
+
);
|
|
4798
|
+
economyAssert(
|
|
4799
|
+
decision.proposedByAccountId !== decision.decidedByAccountId,
|
|
4800
|
+
"ADJUSTMENT_SELF_APPROVAL",
|
|
4801
|
+
"Operator adjustment approval requires a distinct operator"
|
|
4802
|
+
);
|
|
4803
|
+
economyAssert(
|
|
4804
|
+
decision.adjustmentId === preview.adjustmentId && decision.proposalId === proposal.proposalId && decision.proposalHash === expectedProposalHash && decision.previewHash === expectedPreviewHash,
|
|
4805
|
+
"ADJUSTMENT_PREVIEW_MISMATCH",
|
|
4806
|
+
"Operator adjustment decision does not match its preview"
|
|
4807
|
+
);
|
|
4808
|
+
const proposedAt = parseIsoTimestamp(decision.proposedAt);
|
|
4809
|
+
const decidedAt = parseIsoTimestamp(decision.decidedAt);
|
|
4810
|
+
economyAssert(
|
|
4811
|
+
decision.proposedByAccountId === proposal.proposedByAccountId && proposedAt === parseIsoTimestamp(proposal.proposedAt) && decidedAt >= proposedAt,
|
|
4812
|
+
"INVALID_TIME_WINDOW",
|
|
4813
|
+
"Operator adjustment decision times are inconsistent"
|
|
4814
|
+
);
|
|
4815
|
+
economyAssert(
|
|
4816
|
+
decidedAt <= parseIsoTimestamp(preview.expiresAt),
|
|
4817
|
+
"ADJUSTMENT_EXPIRED",
|
|
4818
|
+
"Operator adjustment preview has expired"
|
|
4819
|
+
);
|
|
4820
|
+
}
|
|
4821
|
+
function canonicalOperatorAdjustmentDecisionPayload(decision) {
|
|
4822
|
+
assertExactKeys3(decision, DECISION_KEYS, "Operator adjustment decision");
|
|
4823
|
+
return JSON.stringify({
|
|
4824
|
+
schemaVersion: decision.schemaVersion,
|
|
4825
|
+
decisionId: decision.decisionId,
|
|
4826
|
+
adjustmentId: decision.adjustmentId,
|
|
4827
|
+
proposalId: decision.proposalId,
|
|
4828
|
+
proposalHash: decision.proposalHash,
|
|
4829
|
+
previewHash: decision.previewHash,
|
|
4830
|
+
decision: decision.decision,
|
|
4831
|
+
proposedByAccountId: decision.proposedByAccountId,
|
|
4832
|
+
decidedByAccountId: decision.decidedByAccountId,
|
|
4833
|
+
proposedAt: decision.proposedAt,
|
|
4834
|
+
decidedAt: decision.decidedAt
|
|
4835
|
+
});
|
|
4836
|
+
}
|
|
4837
|
+
function assertOperatorAdjustmentExecution(execution, preview, proposal, decision, expectedPreviewHash, expectedProposalHash, expectedDecisionHash) {
|
|
4838
|
+
assertOperatorAdjustmentDecision(
|
|
4839
|
+
decision,
|
|
4840
|
+
proposal,
|
|
4841
|
+
preview,
|
|
4842
|
+
expectedPreviewHash,
|
|
4843
|
+
expectedProposalHash
|
|
4844
|
+
);
|
|
4845
|
+
assertCanonicalHash6(expectedDecisionHash, "expectedDecisionHash");
|
|
4846
|
+
assertExactKeys3(execution, EXECUTION_KEYS, "Operator adjustment execution");
|
|
4847
|
+
economyAssert(
|
|
4848
|
+
execution.schemaVersion === ECONOMY_CONTRACT_VERSION,
|
|
4849
|
+
"INVALID_CONTRACT",
|
|
4850
|
+
"Unsupported operator adjustment execution"
|
|
4851
|
+
);
|
|
4852
|
+
assertEconomyIdentifier(execution.executionId, "executionId");
|
|
4853
|
+
assertEconomyIdentifier(execution.adjustmentId, "adjustmentId");
|
|
4854
|
+
assertCanonicalHash6(execution.previewHash, "previewHash");
|
|
4855
|
+
assertCanonicalHash6(execution.proposalHash, "proposalHash");
|
|
4856
|
+
assertCanonicalHash6(execution.decisionHash, "decisionHash");
|
|
4857
|
+
assertEconomyIdentifier(execution.sourceLotId, "sourceLotId");
|
|
4858
|
+
assertEconomyIdentifier(execution.transactionId, "transactionId");
|
|
4859
|
+
assertEconomyIdentifier(execution.resultReceiptId, "resultReceiptId");
|
|
4860
|
+
economyAssert(
|
|
4861
|
+
decision.decision === "approve",
|
|
4862
|
+
"ADJUSTMENT_NOT_APPROVED",
|
|
4863
|
+
"Only an approved adjustment may execute"
|
|
4864
|
+
);
|
|
4865
|
+
economyAssert(
|
|
4866
|
+
execution.adjustmentId === preview.adjustmentId && execution.previewHash === expectedPreviewHash && execution.proposalHash === expectedProposalHash && execution.decisionHash === expectedDecisionHash && execution.sourceLotId === preview.sourceLotId,
|
|
4867
|
+
"ADJUSTMENT_PREVIEW_MISMATCH",
|
|
4868
|
+
"Operator adjustment execution does not match its approval plan"
|
|
4869
|
+
);
|
|
4870
|
+
economyAssert(
|
|
4871
|
+
parseIsoTimestamp(execution.executedAt) >= parseIsoTimestamp(decision.decidedAt),
|
|
4872
|
+
"INVALID_TIME_WINDOW",
|
|
4873
|
+
"Operator adjustment execution predates its decision"
|
|
4874
|
+
);
|
|
4875
|
+
}
|
|
4876
|
+
function canonicalOperatorAdjustmentExecutionPayload(execution) {
|
|
4877
|
+
assertExactKeys3(execution, EXECUTION_KEYS, "Operator adjustment execution");
|
|
4878
|
+
return JSON.stringify({
|
|
4879
|
+
schemaVersion: execution.schemaVersion,
|
|
4880
|
+
executionId: execution.executionId,
|
|
4881
|
+
adjustmentId: execution.adjustmentId,
|
|
4882
|
+
previewHash: execution.previewHash,
|
|
4883
|
+
proposalHash: execution.proposalHash,
|
|
4884
|
+
decisionHash: execution.decisionHash,
|
|
4885
|
+
sourceLotId: execution.sourceLotId,
|
|
4886
|
+
transactionId: execution.transactionId,
|
|
4887
|
+
resultReceiptId: execution.resultReceiptId,
|
|
4888
|
+
executedAt: execution.executedAt
|
|
4889
|
+
});
|
|
4890
|
+
}
|
|
4891
|
+
|
|
4525
4892
|
// src/paid-lots.ts
|
|
4526
4893
|
var ZERO_ARITHMETIC = Object.freeze({
|
|
4527
4894
|
retainedDelta: serializeTokenSubunits(0n),
|
|
@@ -7062,7 +7429,7 @@ var PORTABLE_KEYS = /* @__PURE__ */ new Set([
|
|
|
7062
7429
|
"signature",
|
|
7063
7430
|
...PORTABLE_BODY_KEYS
|
|
7064
7431
|
]);
|
|
7065
|
-
function
|
|
7432
|
+
function assertExactKeys4(value, allowedKeys, label) {
|
|
7066
7433
|
economyAssert(
|
|
7067
7434
|
value !== null && typeof value === "object" && !Array.isArray(value),
|
|
7068
7435
|
"INVALID_CONTRACT",
|
|
@@ -7074,7 +7441,7 @@ function assertExactKeys3(value, allowedKeys, label) {
|
|
|
7074
7441
|
`${label} contains an unsupported field`
|
|
7075
7442
|
);
|
|
7076
7443
|
}
|
|
7077
|
-
function
|
|
7444
|
+
function assertCanonicalHash7(value, label) {
|
|
7078
7445
|
economyAssert(
|
|
7079
7446
|
typeof value === "string" && CANONICAL_HASH.test(value),
|
|
7080
7447
|
"INVALID_CONTRACT",
|
|
@@ -7083,7 +7450,7 @@ function assertCanonicalHash6(value, label) {
|
|
|
7083
7450
|
}
|
|
7084
7451
|
function canonicalHash(payload, hashCanonicalPayload2, label) {
|
|
7085
7452
|
const value = hashCanonicalPayload2(payload);
|
|
7086
|
-
|
|
7453
|
+
assertCanonicalHash7(value, label);
|
|
7087
7454
|
return value;
|
|
7088
7455
|
}
|
|
7089
7456
|
function assertUnsignedInteger(value, label) {
|
|
@@ -7151,7 +7518,7 @@ function canonicalSignatureMetadata(signature) {
|
|
|
7151
7518
|
};
|
|
7152
7519
|
}
|
|
7153
7520
|
function assertEconomySealedRecoveryPayload(payload) {
|
|
7154
|
-
|
|
7521
|
+
assertExactKeys4(
|
|
7155
7522
|
payload,
|
|
7156
7523
|
/* @__PURE__ */ new Set([
|
|
7157
7524
|
"schemaVersion",
|
|
@@ -7181,17 +7548,17 @@ function assertEconomySealedRecoveryPayload(payload) {
|
|
|
7181
7548
|
22,
|
|
7182
7549
|
22
|
|
7183
7550
|
);
|
|
7184
|
-
|
|
7551
|
+
assertCanonicalHash7(
|
|
7185
7552
|
payload.plaintextContentHash,
|
|
7186
7553
|
"Recovery plaintext-content hash"
|
|
7187
7554
|
);
|
|
7188
|
-
|
|
7555
|
+
assertCanonicalHash7(
|
|
7189
7556
|
payload.encryptionContextHash,
|
|
7190
7557
|
"Recovery encryption-context hash"
|
|
7191
7558
|
);
|
|
7192
7559
|
}
|
|
7193
7560
|
function assertAcceptanceBody(body) {
|
|
7194
|
-
|
|
7561
|
+
assertExactKeys4(
|
|
7195
7562
|
body,
|
|
7196
7563
|
"acceptanceEnvelopeId" in body ? ACCEPTANCE_KEYS : ACCEPTANCE_BODY_KEYS,
|
|
7197
7564
|
"Recovery acceptance body"
|
|
@@ -7210,9 +7577,9 @@ function assertAcceptanceBody(body) {
|
|
|
7210
7577
|
body.idempotencyFingerprint,
|
|
7211
7578
|
"economy.idempotency-key.v1"
|
|
7212
7579
|
);
|
|
7213
|
-
|
|
7580
|
+
assertCanonicalHash7(body.commandEnvelopeHash, "Command-envelope hash");
|
|
7214
7581
|
assertEconomyIdentifier(body.acceptedReceiptId, "acceptedReceiptId");
|
|
7215
|
-
|
|
7582
|
+
assertCanonicalHash7(body.acceptedReceiptHash, "Accepted-receipt hash");
|
|
7216
7583
|
assertEconomySealedRecoveryPayload(body.sealedPayload);
|
|
7217
7584
|
const preparedAt = parseIsoTimestamp(body.preparedAt);
|
|
7218
7585
|
const acceptedAt = parseIsoTimestamp(body.acceptedAt);
|
|
@@ -7260,7 +7627,7 @@ function createEconomyRecoveryAcceptanceEnvelope(body, hashCanonicalPayload2) {
|
|
|
7260
7627
|
};
|
|
7261
7628
|
}
|
|
7262
7629
|
function assertEconomyRecoveryAcceptanceEnvelope(envelope, hashCanonicalPayload2) {
|
|
7263
|
-
|
|
7630
|
+
assertExactKeys4(envelope, ACCEPTANCE_KEYS, "Recovery acceptance envelope");
|
|
7264
7631
|
assertAcceptanceBody(envelope);
|
|
7265
7632
|
assertEconomyIdentifier(
|
|
7266
7633
|
envelope.acceptanceEnvelopeId,
|
|
@@ -7301,7 +7668,7 @@ function canonicalEconomyRecoveryAcceptanceEnvelopePayload(envelope, hashCanonic
|
|
|
7301
7668
|
});
|
|
7302
7669
|
}
|
|
7303
7670
|
function assertCommittedResultBody(body) {
|
|
7304
|
-
|
|
7671
|
+
assertExactKeys4(
|
|
7305
7672
|
body,
|
|
7306
7673
|
"committedResultId" in body ? COMMITTED_RESULT_KEYS : COMMITTED_RESULT_BODY_KEYS,
|
|
7307
7674
|
"Recovery committed-result body"
|
|
@@ -7329,7 +7696,7 @@ function assertCommittedResultBody(body) {
|
|
|
7329
7696
|
[body.authorityCommitHash, "Authority-commit hash"],
|
|
7330
7697
|
[body.authorityHeadHashAfter, "Authority-head hash"]
|
|
7331
7698
|
]) {
|
|
7332
|
-
|
|
7699
|
+
assertCanonicalHash7(value, label);
|
|
7333
7700
|
}
|
|
7334
7701
|
economyAssert(
|
|
7335
7702
|
RESULT_OUTCOMES.has(body.outcome),
|
|
@@ -7352,7 +7719,7 @@ function assertCommittedResultBody(body) {
|
|
|
7352
7719
|
assertEconomyIdentifier(body.transactionId, "transactionId");
|
|
7353
7720
|
}
|
|
7354
7721
|
if (body.transactionCanonicalHash !== void 0) {
|
|
7355
|
-
|
|
7722
|
+
assertCanonicalHash7(
|
|
7356
7723
|
body.transactionCanonicalHash,
|
|
7357
7724
|
"Transaction canonical hash"
|
|
7358
7725
|
);
|
|
@@ -7395,7 +7762,7 @@ function createEconomyRecoveryCommittedResult(body, hashCanonicalPayload2) {
|
|
|
7395
7762
|
};
|
|
7396
7763
|
}
|
|
7397
7764
|
function assertEconomyRecoveryCommittedResult(result, hashCanonicalPayload2) {
|
|
7398
|
-
|
|
7765
|
+
assertExactKeys4(
|
|
7399
7766
|
result,
|
|
7400
7767
|
COMMITTED_RESULT_KEYS,
|
|
7401
7768
|
"Recovery committed result"
|
|
@@ -7454,7 +7821,7 @@ function assertEconomyRecoveryResultLink(acceptance, result, hashCanonicalPayloa
|
|
|
7454
7821
|
);
|
|
7455
7822
|
}
|
|
7456
7823
|
function assertEconomyEvidenceSignatureMetadata(signature) {
|
|
7457
|
-
|
|
7824
|
+
assertExactKeys4(
|
|
7458
7825
|
signature,
|
|
7459
7826
|
/* @__PURE__ */ new Set([
|
|
7460
7827
|
"schemaVersion",
|
|
@@ -7474,7 +7841,7 @@ function assertEconomyEvidenceSignatureMetadata(signature) {
|
|
|
7474
7841
|
parseIsoTimestamp(signature.signedAt);
|
|
7475
7842
|
}
|
|
7476
7843
|
function assertEconomyEvidenceSignature(signature) {
|
|
7477
|
-
|
|
7844
|
+
assertExactKeys4(
|
|
7478
7845
|
signature,
|
|
7479
7846
|
/* @__PURE__ */ new Set([
|
|
7480
7847
|
"schemaVersion",
|
|
@@ -7496,7 +7863,7 @@ function assertEconomyEvidenceSignature(signature) {
|
|
|
7496
7863
|
assertBase64url(signature.value, "Evidence signature value", 32, 2048);
|
|
7497
7864
|
}
|
|
7498
7865
|
function assertRegionalEvidenceBody(body) {
|
|
7499
|
-
|
|
7866
|
+
assertExactKeys4(
|
|
7500
7867
|
body,
|
|
7501
7868
|
"evidenceReceiptId" in body ? REGIONAL_KEYS : REGIONAL_BODY_KEYS,
|
|
7502
7869
|
"Regional evidence-receipt body"
|
|
@@ -7528,7 +7895,7 @@ function assertRegionalEvidenceBody(body) {
|
|
|
7528
7895
|
"INVALID_CONTRACT",
|
|
7529
7896
|
"Unsupported recovery record kind"
|
|
7530
7897
|
);
|
|
7531
|
-
|
|
7898
|
+
assertCanonicalHash7(
|
|
7532
7899
|
body.recoveryRecordContentHash,
|
|
7533
7900
|
"Recovery-record content hash"
|
|
7534
7901
|
);
|
|
@@ -7544,7 +7911,7 @@ function assertRegionalEvidenceBody(body) {
|
|
|
7544
7911
|
"INVALID_CONTRACT",
|
|
7545
7912
|
"Non-genesis regional evidence receipt requires a previous hash"
|
|
7546
7913
|
);
|
|
7547
|
-
|
|
7914
|
+
assertCanonicalHash7(
|
|
7548
7915
|
body.previousReceiptHash,
|
|
7549
7916
|
"Previous evidence-receipt hash"
|
|
7550
7917
|
);
|
|
@@ -7588,7 +7955,7 @@ function createEconomyRegionalEvidenceReceipt(body, signature, hashCanonicalPayl
|
|
|
7588
7955
|
};
|
|
7589
7956
|
}
|
|
7590
7957
|
function assertEconomyRegionalEvidenceReceipt(receipt, hashCanonicalPayload2) {
|
|
7591
|
-
|
|
7958
|
+
assertExactKeys4(receipt, REGIONAL_KEYS, "Regional evidence receipt");
|
|
7592
7959
|
assertRegionalEvidenceBody(receipt);
|
|
7593
7960
|
assertEconomyIdentifier(receipt.evidenceReceiptId, "evidenceReceiptId");
|
|
7594
7961
|
assertEconomyEvidenceSignature(receipt.signature);
|
|
@@ -7719,7 +8086,7 @@ function assertEconomyRegionalEvidenceChain(receipts, expectedPreviousReceiptHas
|
|
|
7719
8086
|
"INVALID_CONTRACT",
|
|
7720
8087
|
"Partial evidence chain requires its trusted preceding hash"
|
|
7721
8088
|
);
|
|
7722
|
-
|
|
8089
|
+
assertCanonicalHash7(
|
|
7723
8090
|
expectedPreviousReceiptHash,
|
|
7724
8091
|
"Expected preceding evidence-receipt hash"
|
|
7725
8092
|
);
|
|
@@ -7790,7 +8157,7 @@ function assertEconomyRegionalEvidenceEquality(receipts, expectedRegions, hashCa
|
|
|
7790
8157
|
);
|
|
7791
8158
|
}
|
|
7792
8159
|
function assertEconomyMerkleInclusionProof(proof) {
|
|
7793
|
-
|
|
8160
|
+
assertExactKeys4(
|
|
7794
8161
|
proof,
|
|
7795
8162
|
/* @__PURE__ */ new Set([
|
|
7796
8163
|
"schemaVersion",
|
|
@@ -7811,8 +8178,8 @@ function assertEconomyMerkleInclusionProof(proof) {
|
|
|
7811
8178
|
"Unsupported Merkle inclusion proof"
|
|
7812
8179
|
);
|
|
7813
8180
|
assertEconomyIdentifier(proof.anchorId, "anchorId");
|
|
7814
|
-
|
|
7815
|
-
|
|
8181
|
+
assertCanonicalHash7(proof.anchorManifestHash, "Anchor-manifest hash");
|
|
8182
|
+
assertCanonicalHash7(proof.leafHash, "Merkle leaf hash");
|
|
7816
8183
|
assertUnsignedInteger(proof.leafIndex, "Merkle leaf index");
|
|
7817
8184
|
assertUnsignedInteger(proof.leafCount, "Merkle leaf count");
|
|
7818
8185
|
economyAssert(
|
|
@@ -7821,7 +8188,7 @@ function assertEconomyMerkleInclusionProof(proof) {
|
|
|
7821
8188
|
"Merkle leaf position is outside its bounded tree"
|
|
7822
8189
|
);
|
|
7823
8190
|
for (const step of proof.siblings) {
|
|
7824
|
-
|
|
8191
|
+
assertExactKeys4(
|
|
7825
8192
|
step,
|
|
7826
8193
|
/* @__PURE__ */ new Set(["schemaVersion", "side", "hash"]),
|
|
7827
8194
|
"Merkle proof step"
|
|
@@ -7831,7 +8198,7 @@ function assertEconomyMerkleInclusionProof(proof) {
|
|
|
7831
8198
|
"INVALID_CONTRACT",
|
|
7832
8199
|
"Unsupported Merkle proof step"
|
|
7833
8200
|
);
|
|
7834
|
-
|
|
8201
|
+
assertCanonicalHash7(step.hash, "Merkle sibling hash");
|
|
7835
8202
|
}
|
|
7836
8203
|
}
|
|
7837
8204
|
function canonicalMerkleProof(proof) {
|
|
@@ -7910,7 +8277,7 @@ function assertEconomyMerkleInclusion(proof, anchor, hashCanonicalPayload2) {
|
|
|
7910
8277
|
);
|
|
7911
8278
|
}
|
|
7912
8279
|
function assertPortableEvidenceReference(reference) {
|
|
7913
|
-
|
|
8280
|
+
assertExactKeys4(
|
|
7914
8281
|
reference,
|
|
7915
8282
|
/* @__PURE__ */ new Set([
|
|
7916
8283
|
"schemaVersion",
|
|
@@ -7930,7 +8297,7 @@ function assertPortableEvidenceReference(reference) {
|
|
|
7930
8297
|
reference.evidenceReceiptId,
|
|
7931
8298
|
"evidenceReceiptId"
|
|
7932
8299
|
);
|
|
7933
|
-
|
|
8300
|
+
assertCanonicalHash7(
|
|
7934
8301
|
reference.evidenceReceiptHash,
|
|
7935
8302
|
"Evidence-receipt hash"
|
|
7936
8303
|
);
|
|
@@ -7947,7 +8314,7 @@ function canonicalPortableEvidenceReference(reference) {
|
|
|
7947
8314
|
};
|
|
7948
8315
|
}
|
|
7949
8316
|
function assertPortableBody(body) {
|
|
7950
|
-
|
|
8317
|
+
assertExactKeys4(
|
|
7951
8318
|
body,
|
|
7952
8319
|
"portableReceiptId" in body ? PORTABLE_KEYS : PORTABLE_BODY_KEYS,
|
|
7953
8320
|
"Portable customer-receipt body"
|
|
@@ -7986,7 +8353,7 @@ function assertPortableBody(body) {
|
|
|
7986
8353
|
[body.committedResultContentHash, "Committed-result content hash"],
|
|
7987
8354
|
[body.authorityCommitHash, "Authority-commit hash"]
|
|
7988
8355
|
]) {
|
|
7989
|
-
|
|
8356
|
+
assertCanonicalHash7(value, label);
|
|
7990
8357
|
}
|
|
7991
8358
|
assertUnsignedInteger(body.authoritySequence, "Authority sequence");
|
|
7992
8359
|
economyAssert(
|
|
@@ -8071,7 +8438,7 @@ function createEconomyPortableCustomerReceipt(body, signature, hashCanonicalPayl
|
|
|
8071
8438
|
};
|
|
8072
8439
|
}
|
|
8073
8440
|
function assertEconomyPortableCustomerReceipt(receipt, hashCanonicalPayload2) {
|
|
8074
|
-
|
|
8441
|
+
assertExactKeys4(receipt, PORTABLE_KEYS, "Portable customer receipt");
|
|
8075
8442
|
assertPortableBody(receipt);
|
|
8076
8443
|
assertEconomyIdentifier(receipt.portableReceiptId, "portableReceiptId");
|
|
8077
8444
|
assertEconomyEvidenceSignature(receipt.signature);
|
|
@@ -8331,6 +8698,241 @@ function assertSpendRequest(request) {
|
|
|
8331
8698
|
);
|
|
8332
8699
|
}
|
|
8333
8700
|
}
|
|
8701
|
+
|
|
8702
|
+
// src/wallet-initialization.ts
|
|
8703
|
+
var INITIALIZATION_IDENTITY_DOMAIN = "economy.personal-wallet-initialization.identity.v1";
|
|
8704
|
+
var ZERO_TOKEN_SUBUNITS = serializeTokenSubunits(0n);
|
|
8705
|
+
var STATE_KEYS = /* @__PURE__ */ new Set([
|
|
8706
|
+
"schemaVersion",
|
|
8707
|
+
"documentIds",
|
|
8708
|
+
"command",
|
|
8709
|
+
"wallet",
|
|
8710
|
+
"scope",
|
|
8711
|
+
"balance",
|
|
8712
|
+
"lifetime",
|
|
8713
|
+
"activityEntries",
|
|
8714
|
+
"outboxIntent"
|
|
8715
|
+
]);
|
|
8716
|
+
var COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
8717
|
+
"schemaVersion",
|
|
8718
|
+
"commandType",
|
|
8719
|
+
"walletKind",
|
|
8720
|
+
"subjectAccountId",
|
|
8721
|
+
"walletId",
|
|
8722
|
+
"portfolioId",
|
|
8723
|
+
"initializedAt"
|
|
8724
|
+
]);
|
|
8725
|
+
var OUTBOX_KEYS = /* @__PURE__ */ new Set([
|
|
8726
|
+
"schemaVersion",
|
|
8727
|
+
"eventType",
|
|
8728
|
+
"eventId",
|
|
8729
|
+
"subjectAccountId",
|
|
8730
|
+
"walletId",
|
|
8731
|
+
"portfolioId",
|
|
8732
|
+
"occurredAt"
|
|
8733
|
+
]);
|
|
8734
|
+
var DOCUMENT_ID_KEYS = /* @__PURE__ */ new Set([
|
|
8735
|
+
"walletDescriptorId",
|
|
8736
|
+
"accessProjectionId",
|
|
8737
|
+
"balanceProjectionId",
|
|
8738
|
+
"lifetimeProjectionId",
|
|
8739
|
+
"outboxEventId"
|
|
8740
|
+
]);
|
|
8741
|
+
function assertExactKeys5(value, allowed, label) {
|
|
8742
|
+
economyAssert(
|
|
8743
|
+
value !== null && typeof value === "object" && !Array.isArray(value),
|
|
8744
|
+
"INVALID_CONTRACT",
|
|
8745
|
+
`${label} must be an object`
|
|
8746
|
+
);
|
|
8747
|
+
economyAssert(
|
|
8748
|
+
Object.keys(value).every((key) => allowed.has(key)),
|
|
8749
|
+
"INVALID_CONTRACT",
|
|
8750
|
+
`${label} contains an unsupported field`
|
|
8751
|
+
);
|
|
8752
|
+
}
|
|
8753
|
+
function identityDigest(subjectAccountId, hash) {
|
|
8754
|
+
assertEconomyIdentifier(subjectAccountId, "subjectAccountId");
|
|
8755
|
+
const canonicalIdentity = JSON.stringify({
|
|
8756
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8757
|
+
domain: INITIALIZATION_IDENTITY_DOMAIN,
|
|
8758
|
+
subjectAccountId
|
|
8759
|
+
});
|
|
8760
|
+
const canonicalHash2 = hash(canonicalIdentity);
|
|
8761
|
+
economyAssert(
|
|
8762
|
+
/^sha256:[a-f0-9]{64}$/u.test(canonicalHash2),
|
|
8763
|
+
"INVALID_CONTRACT",
|
|
8764
|
+
"Wallet initialization identity hash must be canonical SHA-256"
|
|
8765
|
+
);
|
|
8766
|
+
return canonicalHash2.slice("sha256:".length);
|
|
8767
|
+
}
|
|
8768
|
+
function createPersonalWalletInitializationDocumentIds(subjectAccountId, hash) {
|
|
8769
|
+
const digest = identityDigest(subjectAccountId, hash);
|
|
8770
|
+
return {
|
|
8771
|
+
walletId: `wallet:personal:${digest}`,
|
|
8772
|
+
portfolioId: `portfolio:self:${digest}`,
|
|
8773
|
+
walletDescriptorId: `wallet-descriptor:${digest}`,
|
|
8774
|
+
accessProjectionId: `wallet-access:${digest}`,
|
|
8775
|
+
balanceProjectionId: `wallet-balance:${digest}`,
|
|
8776
|
+
lifetimeProjectionId: `wallet-lifetime:${digest}`,
|
|
8777
|
+
outboxEventId: `outbox:wallet-initialized:${digest}`
|
|
8778
|
+
};
|
|
8779
|
+
}
|
|
8780
|
+
function assertPersonalWalletInitializationCommand(command) {
|
|
8781
|
+
assertExactKeys5(command, COMMAND_KEYS, "Wallet initialization command");
|
|
8782
|
+
economyAssert(
|
|
8783
|
+
command.schemaVersion === ECONOMY_CONTRACT_VERSION && command.commandType === "initialize-wallet" && command.walletKind === "personal",
|
|
8784
|
+
"INVALID_CONTRACT",
|
|
8785
|
+
"Unsupported personal-wallet initialization command"
|
|
8786
|
+
);
|
|
8787
|
+
assertEconomyIdentifier(command.subjectAccountId, "subjectAccountId");
|
|
8788
|
+
assertEconomyIdentifier(command.walletId, "walletId");
|
|
8789
|
+
assertEconomyIdentifier(command.portfolioId, "portfolioId");
|
|
8790
|
+
parseIsoTimestamp(command.initializedAt);
|
|
8791
|
+
}
|
|
8792
|
+
function canonicalPersonalWalletInitializationCommandPayload(command) {
|
|
8793
|
+
assertPersonalWalletInitializationCommand(command);
|
|
8794
|
+
return JSON.stringify({
|
|
8795
|
+
schemaVersion: command.schemaVersion,
|
|
8796
|
+
commandType: command.commandType,
|
|
8797
|
+
walletKind: command.walletKind,
|
|
8798
|
+
subjectAccountId: command.subjectAccountId,
|
|
8799
|
+
walletId: command.walletId,
|
|
8800
|
+
portfolioId: command.portfolioId,
|
|
8801
|
+
initializedAt: command.initializedAt
|
|
8802
|
+
});
|
|
8803
|
+
}
|
|
8804
|
+
function assertPersonalWalletInitializationOutboxIntent(intent) {
|
|
8805
|
+
assertExactKeys5(intent, OUTBOX_KEYS, "Wallet initialization outbox intent");
|
|
8806
|
+
economyAssert(
|
|
8807
|
+
intent.schemaVersion === ECONOMY_CONTRACT_VERSION && intent.eventType === "wallet.initialized.v1",
|
|
8808
|
+
"INVALID_CONTRACT",
|
|
8809
|
+
"Unsupported wallet initialization outbox intent"
|
|
8810
|
+
);
|
|
8811
|
+
assertEconomyIdentifier(intent.eventId, "eventId");
|
|
8812
|
+
assertEconomyIdentifier(intent.subjectAccountId, "subjectAccountId");
|
|
8813
|
+
assertEconomyIdentifier(intent.walletId, "walletId");
|
|
8814
|
+
assertEconomyIdentifier(intent.portfolioId, "portfolioId");
|
|
8815
|
+
parseIsoTimestamp(intent.occurredAt);
|
|
8816
|
+
}
|
|
8817
|
+
function canonicalPersonalWalletInitializationOutboxPayload(intent) {
|
|
8818
|
+
assertPersonalWalletInitializationOutboxIntent(intent);
|
|
8819
|
+
return JSON.stringify({
|
|
8820
|
+
schemaVersion: intent.schemaVersion,
|
|
8821
|
+
eventType: intent.eventType,
|
|
8822
|
+
eventId: intent.eventId,
|
|
8823
|
+
subjectAccountId: intent.subjectAccountId,
|
|
8824
|
+
walletId: intent.walletId,
|
|
8825
|
+
portfolioId: intent.portfolioId,
|
|
8826
|
+
occurredAt: intent.occurredAt
|
|
8827
|
+
});
|
|
8828
|
+
}
|
|
8829
|
+
function createPersonalWalletInitializationState(input, hash) {
|
|
8830
|
+
parseIsoTimestamp(input.initializedAt);
|
|
8831
|
+
const { walletId, portfolioId, ...documentIds } = createPersonalWalletInitializationDocumentIds(
|
|
8832
|
+
input.subjectAccountId,
|
|
8833
|
+
hash
|
|
8834
|
+
);
|
|
8835
|
+
const command = {
|
|
8836
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8837
|
+
commandType: "initialize-wallet",
|
|
8838
|
+
walletKind: "personal",
|
|
8839
|
+
subjectAccountId: input.subjectAccountId,
|
|
8840
|
+
walletId,
|
|
8841
|
+
portfolioId,
|
|
8842
|
+
initializedAt: input.initializedAt
|
|
8843
|
+
};
|
|
8844
|
+
const state = {
|
|
8845
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8846
|
+
documentIds,
|
|
8847
|
+
command,
|
|
8848
|
+
wallet: {
|
|
8849
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8850
|
+
walletId,
|
|
8851
|
+
accountId: input.subjectAccountId,
|
|
8852
|
+
kind: "personal",
|
|
8853
|
+
ownerType: "account",
|
|
8854
|
+
ownerId: input.subjectAccountId,
|
|
8855
|
+
status: "active",
|
|
8856
|
+
version: 1,
|
|
8857
|
+
createdAt: input.initializedAt
|
|
8858
|
+
},
|
|
8859
|
+
scope: {
|
|
8860
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8861
|
+
portfolioId,
|
|
8862
|
+
subjectAccountId: input.subjectAccountId,
|
|
8863
|
+
components: [{ walletId, role: "personal" }]
|
|
8864
|
+
},
|
|
8865
|
+
balance: {
|
|
8866
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8867
|
+
walletId,
|
|
8868
|
+
available: ZERO_TOKEN_SUBUNITS,
|
|
8869
|
+
reserved: ZERO_TOKEN_SUBUNITS,
|
|
8870
|
+
held: ZERO_TOKEN_SUBUNITS,
|
|
8871
|
+
rewardProgress: ZERO_TOKEN_SUBUNITS,
|
|
8872
|
+
version: 1,
|
|
8873
|
+
asOf: input.initializedAt
|
|
8874
|
+
},
|
|
8875
|
+
lifetime: {
|
|
8876
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8877
|
+
walletId,
|
|
8878
|
+
totals: {
|
|
8879
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8880
|
+
bought: ZERO_TOKEN_SUBUNITS,
|
|
8881
|
+
earned: ZERO_TOKEN_SUBUNITS,
|
|
8882
|
+
allocated: ZERO_TOKEN_SUBUNITS,
|
|
8883
|
+
reclaimed: ZERO_TOKEN_SUBUNITS,
|
|
8884
|
+
spent: ZERO_TOKEN_SUBUNITS,
|
|
8885
|
+
reversed: ZERO_TOKEN_SUBUNITS
|
|
8886
|
+
},
|
|
8887
|
+
version: 1,
|
|
8888
|
+
asOf: input.initializedAt
|
|
8889
|
+
},
|
|
8890
|
+
activityEntries: [],
|
|
8891
|
+
outboxIntent: {
|
|
8892
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8893
|
+
eventType: "wallet.initialized.v1",
|
|
8894
|
+
eventId: documentIds.outboxEventId,
|
|
8895
|
+
subjectAccountId: input.subjectAccountId,
|
|
8896
|
+
walletId,
|
|
8897
|
+
portfolioId,
|
|
8898
|
+
occurredAt: input.initializedAt
|
|
8899
|
+
}
|
|
8900
|
+
};
|
|
8901
|
+
assertPersonalWalletInitializationState(state);
|
|
8902
|
+
return state;
|
|
8903
|
+
}
|
|
8904
|
+
function assertPersonalWalletInitializationState(state) {
|
|
8905
|
+
assertExactKeys5(state, STATE_KEYS, "Wallet initialization state");
|
|
8906
|
+
assertExactKeys5(
|
|
8907
|
+
state.documentIds,
|
|
8908
|
+
DOCUMENT_ID_KEYS,
|
|
8909
|
+
"Wallet initialization document IDs"
|
|
8910
|
+
);
|
|
8911
|
+
economyAssert(
|
|
8912
|
+
state.schemaVersion === ECONOMY_CONTRACT_VERSION,
|
|
8913
|
+
"INVALID_CONTRACT",
|
|
8914
|
+
"Unsupported wallet initialization state"
|
|
8915
|
+
);
|
|
8916
|
+
for (const identifier of Object.values(state.documentIds)) {
|
|
8917
|
+
assertEconomyIdentifier(identifier, "wallet initialization document ID");
|
|
8918
|
+
}
|
|
8919
|
+
economyAssert(
|
|
8920
|
+
new Set(Object.values(state.documentIds)).size === Object.values(state.documentIds).length,
|
|
8921
|
+
"INVALID_CONTRACT",
|
|
8922
|
+
"Wallet initialization document IDs must be unique"
|
|
8923
|
+
);
|
|
8924
|
+
assertPersonalWalletInitializationCommand(state.command);
|
|
8925
|
+
assertWallet(state.wallet);
|
|
8926
|
+
assertWalletPortfolioReadScope(state.scope);
|
|
8927
|
+
assertWalletBalanceSummary(state.balance);
|
|
8928
|
+
assertWalletLifetimeSnapshot(state.lifetime);
|
|
8929
|
+
assertPersonalWalletInitializationOutboxIntent(state.outboxIntent);
|
|
8930
|
+
economyAssert(
|
|
8931
|
+
state.wallet.walletId === state.command.walletId && state.wallet.accountId === state.command.subjectAccountId && state.wallet.ownerId === state.command.subjectAccountId && state.wallet.kind === "personal" && state.wallet.ownerType === "account" && state.wallet.createdAt === state.command.initializedAt && state.scope.portfolioId === state.command.portfolioId && state.scope.subjectAccountId === state.command.subjectAccountId && state.scope.components.length === 1 && state.scope.components[0]?.walletId === state.command.walletId && state.scope.components[0]?.role === "personal" && state.scope.components[0]?.beneficiaryAccountId === void 0 && state.balance.walletId === state.command.walletId && state.balance.available === ZERO_TOKEN_SUBUNITS && state.balance.reserved === ZERO_TOKEN_SUBUNITS && state.balance.held === ZERO_TOKEN_SUBUNITS && state.balance.rewardProgress === ZERO_TOKEN_SUBUNITS && state.balance.version === 1 && state.balance.asOf === state.command.initializedAt && state.lifetime.walletId === state.command.walletId && state.lifetime.version === 1 && state.lifetime.asOf === state.command.initializedAt && state.lifetime.totals.bought === ZERO_TOKEN_SUBUNITS && state.lifetime.totals.earned === ZERO_TOKEN_SUBUNITS && state.lifetime.totals.allocated === ZERO_TOKEN_SUBUNITS && state.lifetime.totals.reclaimed === ZERO_TOKEN_SUBUNITS && state.lifetime.totals.spent === ZERO_TOKEN_SUBUNITS && state.lifetime.totals.reversed === ZERO_TOKEN_SUBUNITS && state.activityEntries.length === 0 && state.outboxIntent.eventId === state.documentIds.outboxEventId && state.outboxIntent.subjectAccountId === state.command.subjectAccountId && state.outboxIntent.walletId === state.command.walletId && state.outboxIntent.portfolioId === state.command.portfolioId && state.outboxIntent.occurredAt === state.command.initializedAt,
|
|
8932
|
+
"INVALID_CONTRACT",
|
|
8933
|
+
"Personal-wallet initialization state is incomplete or inconsistent"
|
|
8934
|
+
);
|
|
8935
|
+
}
|
|
8334
8936
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8335
8937
|
0 && (module.exports = {
|
|
8336
8938
|
BASELINE_GBP_CATALOG_VERSION,
|
|
@@ -8413,9 +9015,16 @@ function assertSpendRequest(request) {
|
|
|
8413
9015
|
assertModuleSpendQuote,
|
|
8414
9016
|
assertNonNegativeAccounts,
|
|
8415
9017
|
assertOpenPurchaseIntent,
|
|
9018
|
+
assertOperatorAdjustmentDecision,
|
|
9019
|
+
assertOperatorAdjustmentExecution,
|
|
9020
|
+
assertOperatorAdjustmentPreview,
|
|
9021
|
+
assertOperatorAdjustmentProposal,
|
|
8416
9022
|
assertPaidLotLifecycle,
|
|
8417
9023
|
assertPaidLotLifecycleEvent,
|
|
8418
9024
|
assertPaidLotPurchaseProvenance,
|
|
9025
|
+
assertPersonalWalletInitializationCommand,
|
|
9026
|
+
assertPersonalWalletInitializationOutboxIntent,
|
|
9027
|
+
assertPersonalWalletInitializationState,
|
|
8419
9028
|
assertPurchaseCapReservation,
|
|
8420
9029
|
assertPurchaseCapReservationTransition,
|
|
8421
9030
|
assertPurchaseIntentBinding,
|
|
@@ -8473,6 +9082,12 @@ function assertSpendRequest(request) {
|
|
|
8473
9082
|
canonicalEconomyRegionalEvidenceReceiptBodyPayload,
|
|
8474
9083
|
canonicalEconomyRegionalEvidenceReceiptPayload,
|
|
8475
9084
|
canonicalEconomyRegionalEvidenceReceiptSigningPayload,
|
|
9085
|
+
canonicalOperatorAdjustmentDecisionPayload,
|
|
9086
|
+
canonicalOperatorAdjustmentExecutionPayload,
|
|
9087
|
+
canonicalOperatorAdjustmentPreviewPayload,
|
|
9088
|
+
canonicalOperatorAdjustmentProposalPayload,
|
|
9089
|
+
canonicalPersonalWalletInitializationCommandPayload,
|
|
9090
|
+
canonicalPersonalWalletInitializationOutboxPayload,
|
|
8476
9091
|
canonicalTransactionPayload,
|
|
8477
9092
|
closeModuleAllowance,
|
|
8478
9093
|
convertRewardPayout,
|
|
@@ -8488,6 +9103,8 @@ function assertSpendRequest(request) {
|
|
|
8488
9103
|
createModuleSpendHold,
|
|
8489
9104
|
createModuleSpendQuote,
|
|
8490
9105
|
createPaidLotLifecycle,
|
|
9106
|
+
createPersonalWalletInitializationDocumentIds,
|
|
9107
|
+
createPersonalWalletInitializationState,
|
|
8491
9108
|
createProjectionSnapshot,
|
|
8492
9109
|
createPurchaseIntentLifecycle,
|
|
8493
9110
|
createReversalTransaction,
|