@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.js
CHANGED
|
@@ -745,7 +745,8 @@ var COMMAND_TYPES = /* @__PURE__ */ new Set([
|
|
|
745
745
|
"refund",
|
|
746
746
|
"chargeback",
|
|
747
747
|
"reverse",
|
|
748
|
-
"adjust"
|
|
748
|
+
"adjust",
|
|
749
|
+
"initialize-wallet"
|
|
749
750
|
]);
|
|
750
751
|
var COMMAND_SOURCES = /* @__PURE__ */ new Set([
|
|
751
752
|
"browser",
|
|
@@ -792,7 +793,8 @@ var SOURCE_COMMAND_TYPES = {
|
|
|
792
793
|
"reclaim",
|
|
793
794
|
"spend",
|
|
794
795
|
"hold",
|
|
795
|
-
"release-hold"
|
|
796
|
+
"release-hold",
|
|
797
|
+
"initialize-wallet"
|
|
796
798
|
]),
|
|
797
799
|
shopify: /* @__PURE__ */ new Set([
|
|
798
800
|
"credit-purchase",
|
|
@@ -987,6 +989,13 @@ function assertCommandSourcePrincipal(envelope) {
|
|
|
987
989
|
"Delegated-child commands require a distinct actor and relationship"
|
|
988
990
|
);
|
|
989
991
|
}
|
|
992
|
+
if (envelope.commandType === "initialize-wallet") {
|
|
993
|
+
economyAssert(
|
|
994
|
+
envelope.commandSource === "browser" && envelope.principalType === "account" && envelope.actorAccountId === envelope.subjectAccountId && envelope.relationshipId === void 0 && envelope.authorizationVersion === void 0,
|
|
995
|
+
"INVALID_CONTRACT",
|
|
996
|
+
"Wallet initialization requires a direct self-account browser command"
|
|
997
|
+
);
|
|
998
|
+
}
|
|
990
999
|
}
|
|
991
1000
|
function assertAuditedEconomyCommandEnvelope(envelope) {
|
|
992
1001
|
assertExactKeys(
|
|
@@ -1588,6 +1597,7 @@ var RECORD_KINDS = /* @__PURE__ */ new Set([
|
|
|
1588
1597
|
"source-lot",
|
|
1589
1598
|
"source-lot-movement",
|
|
1590
1599
|
"gameplay-allocation",
|
|
1600
|
+
"wallet",
|
|
1591
1601
|
"balance-projection",
|
|
1592
1602
|
"lifetime-projection",
|
|
1593
1603
|
"idempotency-result",
|
|
@@ -2775,6 +2785,13 @@ function assertReceiptGraph(graph, commandEnvelopeHash, hash, acceptanceCommit,
|
|
|
2775
2785
|
result.receiptId,
|
|
2776
2786
|
resultHash
|
|
2777
2787
|
);
|
|
2788
|
+
if (envelope.commandType === "initialize-wallet") {
|
|
2789
|
+
economyAssert(
|
|
2790
|
+
result.outcome === "no-op" && (result.noOpCode === "WALLET_INITIALIZED" || result.noOpCode === "WALLET_ALREADY_INITIALIZED"),
|
|
2791
|
+
"INVALID_CONTRACT",
|
|
2792
|
+
"Wallet initialization must terminate without an economic transaction"
|
|
2793
|
+
);
|
|
2794
|
+
}
|
|
2778
2795
|
if (result.outcome !== "completed") {
|
|
2779
2796
|
economyAssert(
|
|
2780
2797
|
graph.transaction === void 0,
|
|
@@ -4302,6 +4319,341 @@ function assertDistinctAdjustmentApproval(request) {
|
|
|
4302
4319
|
}
|
|
4303
4320
|
}
|
|
4304
4321
|
|
|
4322
|
+
// src/operator-adjustments.ts
|
|
4323
|
+
var PREVIEW_KEYS = /* @__PURE__ */ new Set([
|
|
4324
|
+
"schemaVersion",
|
|
4325
|
+
"previewId",
|
|
4326
|
+
"adjustmentId",
|
|
4327
|
+
"operation",
|
|
4328
|
+
"targetAccountId",
|
|
4329
|
+
"targetComponent",
|
|
4330
|
+
"targetWalletId",
|
|
4331
|
+
"targetLedgerAccountId",
|
|
4332
|
+
"offsetLedgerAccountId",
|
|
4333
|
+
"sourceLotId",
|
|
4334
|
+
"amount",
|
|
4335
|
+
"reasonCode",
|
|
4336
|
+
"ticketReferenceHash",
|
|
4337
|
+
"transferPolicy",
|
|
4338
|
+
"refundPolicy",
|
|
4339
|
+
"originalSourceLotId",
|
|
4340
|
+
"originalTransactionId",
|
|
4341
|
+
"preparedAt",
|
|
4342
|
+
"expiresAt"
|
|
4343
|
+
]);
|
|
4344
|
+
var DECISION_KEYS = /* @__PURE__ */ new Set([
|
|
4345
|
+
"schemaVersion",
|
|
4346
|
+
"decisionId",
|
|
4347
|
+
"adjustmentId",
|
|
4348
|
+
"proposalId",
|
|
4349
|
+
"proposalHash",
|
|
4350
|
+
"previewHash",
|
|
4351
|
+
"decision",
|
|
4352
|
+
"proposedByAccountId",
|
|
4353
|
+
"decidedByAccountId",
|
|
4354
|
+
"proposedAt",
|
|
4355
|
+
"decidedAt"
|
|
4356
|
+
]);
|
|
4357
|
+
var PROPOSAL_KEYS = /* @__PURE__ */ new Set([
|
|
4358
|
+
"schemaVersion",
|
|
4359
|
+
"proposalId",
|
|
4360
|
+
"adjustmentId",
|
|
4361
|
+
"previewHash",
|
|
4362
|
+
"status",
|
|
4363
|
+
"proposedByAccountId",
|
|
4364
|
+
"proposedAt",
|
|
4365
|
+
"expiresAt"
|
|
4366
|
+
]);
|
|
4367
|
+
var EXECUTION_KEYS = /* @__PURE__ */ new Set([
|
|
4368
|
+
"schemaVersion",
|
|
4369
|
+
"executionId",
|
|
4370
|
+
"adjustmentId",
|
|
4371
|
+
"previewHash",
|
|
4372
|
+
"proposalHash",
|
|
4373
|
+
"decisionHash",
|
|
4374
|
+
"sourceLotId",
|
|
4375
|
+
"transactionId",
|
|
4376
|
+
"resultReceiptId",
|
|
4377
|
+
"executedAt"
|
|
4378
|
+
]);
|
|
4379
|
+
var OPERATIONS = /* @__PURE__ */ new Set([
|
|
4380
|
+
"credit",
|
|
4381
|
+
"reverse-credit"
|
|
4382
|
+
]);
|
|
4383
|
+
var TARGET_COMPONENTS = /* @__PURE__ */ new Set([
|
|
4384
|
+
"personal",
|
|
4385
|
+
"household-treasury"
|
|
4386
|
+
]);
|
|
4387
|
+
var TRANSFER_POLICIES = /* @__PURE__ */ new Set([
|
|
4388
|
+
"household-allocatable",
|
|
4389
|
+
"same-user-only",
|
|
4390
|
+
"non-transferable"
|
|
4391
|
+
]);
|
|
4392
|
+
var DECISIONS = /* @__PURE__ */ new Set([
|
|
4393
|
+
"approve",
|
|
4394
|
+
"reject"
|
|
4395
|
+
]);
|
|
4396
|
+
function assertExactKeys3(value, allowed, label) {
|
|
4397
|
+
economyAssert(
|
|
4398
|
+
value !== null && typeof value === "object" && !Array.isArray(value),
|
|
4399
|
+
"INVALID_CONTRACT",
|
|
4400
|
+
`${label} must be an object`
|
|
4401
|
+
);
|
|
4402
|
+
economyAssert(
|
|
4403
|
+
Object.keys(value).every((key) => allowed.has(key)),
|
|
4404
|
+
"INVALID_CONTRACT",
|
|
4405
|
+
`${label} contains an unsupported field`
|
|
4406
|
+
);
|
|
4407
|
+
}
|
|
4408
|
+
function assertCanonicalHash6(value, label) {
|
|
4409
|
+
economyAssert(
|
|
4410
|
+
/^sha256:[a-f0-9]{64}$/u.test(value),
|
|
4411
|
+
"INVALID_CONTRACT",
|
|
4412
|
+
`${label} must be a canonical SHA-256 reference`
|
|
4413
|
+
);
|
|
4414
|
+
}
|
|
4415
|
+
function assertReasonCode(reasonCode) {
|
|
4416
|
+
economyAssert(
|
|
4417
|
+
/^[A-Z][A-Z0-9_]{2,95}$/u.test(reasonCode),
|
|
4418
|
+
"INVALID_CONTRACT",
|
|
4419
|
+
"Adjustment reasonCode must be a bounded uppercase identifier"
|
|
4420
|
+
);
|
|
4421
|
+
}
|
|
4422
|
+
function assertOperatorAdjustmentPreview(preview) {
|
|
4423
|
+
assertExactKeys3(preview, PREVIEW_KEYS, "Operator adjustment preview");
|
|
4424
|
+
economyAssert(
|
|
4425
|
+
preview.schemaVersion === ECONOMY_CONTRACT_VERSION && OPERATIONS.has(preview.operation) && TARGET_COMPONENTS.has(preview.targetComponent) && TRANSFER_POLICIES.has(preview.transferPolicy) && preview.refundPolicy === "not-refundable",
|
|
4426
|
+
"INVALID_CONTRACT",
|
|
4427
|
+
"Unsupported operator adjustment preview"
|
|
4428
|
+
);
|
|
4429
|
+
assertEconomyIdentifier(preview.previewId, "previewId");
|
|
4430
|
+
assertEconomyIdentifier(preview.adjustmentId, "adjustmentId");
|
|
4431
|
+
assertEconomyIdentifier(preview.targetAccountId, "targetAccountId");
|
|
4432
|
+
assertEconomyIdentifier(preview.targetWalletId, "targetWalletId");
|
|
4433
|
+
assertEconomyIdentifier(
|
|
4434
|
+
preview.targetLedgerAccountId,
|
|
4435
|
+
"targetLedgerAccountId"
|
|
4436
|
+
);
|
|
4437
|
+
assertEconomyIdentifier(
|
|
4438
|
+
preview.offsetLedgerAccountId,
|
|
4439
|
+
"offsetLedgerAccountId"
|
|
4440
|
+
);
|
|
4441
|
+
assertEconomyIdentifier(preview.sourceLotId, "sourceLotId");
|
|
4442
|
+
economyAssert(
|
|
4443
|
+
parseTokenSubunits(preview.amount) > 0n,
|
|
4444
|
+
"INVALID_AMOUNT",
|
|
4445
|
+
"Operator adjustment amount must be positive"
|
|
4446
|
+
);
|
|
4447
|
+
assertReasonCode(preview.reasonCode);
|
|
4448
|
+
assertCanonicalHash6(preview.ticketReferenceHash, "ticketReferenceHash");
|
|
4449
|
+
const preparedAt = parseIsoTimestamp(preview.preparedAt);
|
|
4450
|
+
const expiresAt = parseIsoTimestamp(preview.expiresAt);
|
|
4451
|
+
economyAssert(
|
|
4452
|
+
expiresAt > preparedAt,
|
|
4453
|
+
"INVALID_TIME_WINDOW",
|
|
4454
|
+
"Operator adjustment preview must expire after preparation"
|
|
4455
|
+
);
|
|
4456
|
+
if (preview.operation === "credit") {
|
|
4457
|
+
economyAssert(
|
|
4458
|
+
preview.originalSourceLotId === void 0 && preview.originalTransactionId === void 0,
|
|
4459
|
+
"INVALID_CONTRACT",
|
|
4460
|
+
"A credit preview cannot bind an original transaction"
|
|
4461
|
+
);
|
|
4462
|
+
return;
|
|
4463
|
+
}
|
|
4464
|
+
economyAssert(
|
|
4465
|
+
preview.originalSourceLotId !== void 0 && preview.originalTransactionId !== void 0,
|
|
4466
|
+
"INVALID_CONTRACT",
|
|
4467
|
+
"A reversal preview must bind the original lot and transaction"
|
|
4468
|
+
);
|
|
4469
|
+
assertEconomyIdentifier(preview.originalSourceLotId, "originalSourceLotId");
|
|
4470
|
+
assertEconomyIdentifier(
|
|
4471
|
+
preview.originalTransactionId,
|
|
4472
|
+
"originalTransactionId"
|
|
4473
|
+
);
|
|
4474
|
+
}
|
|
4475
|
+
function canonicalOperatorAdjustmentPreviewPayload(preview) {
|
|
4476
|
+
assertOperatorAdjustmentPreview(preview);
|
|
4477
|
+
return JSON.stringify({
|
|
4478
|
+
schemaVersion: preview.schemaVersion,
|
|
4479
|
+
previewId: preview.previewId,
|
|
4480
|
+
adjustmentId: preview.adjustmentId,
|
|
4481
|
+
operation: preview.operation,
|
|
4482
|
+
targetAccountId: preview.targetAccountId,
|
|
4483
|
+
targetComponent: preview.targetComponent,
|
|
4484
|
+
targetWalletId: preview.targetWalletId,
|
|
4485
|
+
targetLedgerAccountId: preview.targetLedgerAccountId,
|
|
4486
|
+
offsetLedgerAccountId: preview.offsetLedgerAccountId,
|
|
4487
|
+
sourceLotId: preview.sourceLotId,
|
|
4488
|
+
amount: preview.amount,
|
|
4489
|
+
reasonCode: preview.reasonCode,
|
|
4490
|
+
ticketReferenceHash: preview.ticketReferenceHash,
|
|
4491
|
+
transferPolicy: preview.transferPolicy,
|
|
4492
|
+
refundPolicy: preview.refundPolicy,
|
|
4493
|
+
...preview.originalSourceLotId === void 0 ? {} : { originalSourceLotId: preview.originalSourceLotId },
|
|
4494
|
+
...preview.originalTransactionId === void 0 ? {} : { originalTransactionId: preview.originalTransactionId },
|
|
4495
|
+
preparedAt: preview.preparedAt,
|
|
4496
|
+
expiresAt: preview.expiresAt
|
|
4497
|
+
});
|
|
4498
|
+
}
|
|
4499
|
+
function assertOperatorAdjustmentProposal(proposal, preview, expectedPreviewHash) {
|
|
4500
|
+
assertOperatorAdjustmentPreview(preview);
|
|
4501
|
+
assertCanonicalHash6(expectedPreviewHash, "expectedPreviewHash");
|
|
4502
|
+
assertExactKeys3(proposal, PROPOSAL_KEYS, "Operator adjustment proposal");
|
|
4503
|
+
economyAssert(
|
|
4504
|
+
proposal.schemaVersion === ECONOMY_CONTRACT_VERSION && proposal.status === "pending-approval",
|
|
4505
|
+
"INVALID_CONTRACT",
|
|
4506
|
+
"Unsupported operator adjustment proposal"
|
|
4507
|
+
);
|
|
4508
|
+
assertEconomyIdentifier(proposal.proposalId, "proposalId");
|
|
4509
|
+
assertEconomyIdentifier(proposal.adjustmentId, "adjustmentId");
|
|
4510
|
+
assertCanonicalHash6(proposal.previewHash, "previewHash");
|
|
4511
|
+
assertEconomyIdentifier(
|
|
4512
|
+
proposal.proposedByAccountId,
|
|
4513
|
+
"proposedByAccountId"
|
|
4514
|
+
);
|
|
4515
|
+
economyAssert(
|
|
4516
|
+
proposal.adjustmentId === preview.adjustmentId && proposal.previewHash === expectedPreviewHash,
|
|
4517
|
+
"ADJUSTMENT_PREVIEW_MISMATCH",
|
|
4518
|
+
"Operator adjustment proposal does not match its preview"
|
|
4519
|
+
);
|
|
4520
|
+
const proposedAt = parseIsoTimestamp(proposal.proposedAt);
|
|
4521
|
+
const expiresAt = parseIsoTimestamp(proposal.expiresAt);
|
|
4522
|
+
economyAssert(
|
|
4523
|
+
proposedAt >= parseIsoTimestamp(preview.preparedAt) && expiresAt === parseIsoTimestamp(preview.expiresAt) && expiresAt > proposedAt,
|
|
4524
|
+
"INVALID_TIME_WINDOW",
|
|
4525
|
+
"Operator adjustment proposal times are inconsistent"
|
|
4526
|
+
);
|
|
4527
|
+
}
|
|
4528
|
+
function canonicalOperatorAdjustmentProposalPayload(proposal) {
|
|
4529
|
+
assertExactKeys3(proposal, PROPOSAL_KEYS, "Operator adjustment proposal");
|
|
4530
|
+
return JSON.stringify({
|
|
4531
|
+
schemaVersion: proposal.schemaVersion,
|
|
4532
|
+
proposalId: proposal.proposalId,
|
|
4533
|
+
adjustmentId: proposal.adjustmentId,
|
|
4534
|
+
previewHash: proposal.previewHash,
|
|
4535
|
+
status: proposal.status,
|
|
4536
|
+
proposedByAccountId: proposal.proposedByAccountId,
|
|
4537
|
+
proposedAt: proposal.proposedAt,
|
|
4538
|
+
expiresAt: proposal.expiresAt
|
|
4539
|
+
});
|
|
4540
|
+
}
|
|
4541
|
+
function assertOperatorAdjustmentDecision(decision, proposal, preview, expectedPreviewHash, expectedProposalHash) {
|
|
4542
|
+
assertOperatorAdjustmentProposal(proposal, preview, expectedPreviewHash);
|
|
4543
|
+
assertCanonicalHash6(expectedProposalHash, "expectedProposalHash");
|
|
4544
|
+
assertExactKeys3(decision, DECISION_KEYS, "Operator adjustment decision");
|
|
4545
|
+
economyAssert(
|
|
4546
|
+
decision.schemaVersion === ECONOMY_CONTRACT_VERSION && DECISIONS.has(decision.decision),
|
|
4547
|
+
"INVALID_CONTRACT",
|
|
4548
|
+
"Unsupported operator adjustment decision"
|
|
4549
|
+
);
|
|
4550
|
+
assertEconomyIdentifier(decision.decisionId, "decisionId");
|
|
4551
|
+
assertEconomyIdentifier(decision.adjustmentId, "adjustmentId");
|
|
4552
|
+
assertEconomyIdentifier(decision.proposalId, "proposalId");
|
|
4553
|
+
assertCanonicalHash6(decision.proposalHash, "proposalHash");
|
|
4554
|
+
assertCanonicalHash6(decision.previewHash, "previewHash");
|
|
4555
|
+
assertEconomyIdentifier(
|
|
4556
|
+
decision.proposedByAccountId,
|
|
4557
|
+
"proposedByAccountId"
|
|
4558
|
+
);
|
|
4559
|
+
assertEconomyIdentifier(
|
|
4560
|
+
decision.decidedByAccountId,
|
|
4561
|
+
"decidedByAccountId"
|
|
4562
|
+
);
|
|
4563
|
+
economyAssert(
|
|
4564
|
+
decision.proposedByAccountId !== decision.decidedByAccountId,
|
|
4565
|
+
"ADJUSTMENT_SELF_APPROVAL",
|
|
4566
|
+
"Operator adjustment approval requires a distinct operator"
|
|
4567
|
+
);
|
|
4568
|
+
economyAssert(
|
|
4569
|
+
decision.adjustmentId === preview.adjustmentId && decision.proposalId === proposal.proposalId && decision.proposalHash === expectedProposalHash && decision.previewHash === expectedPreviewHash,
|
|
4570
|
+
"ADJUSTMENT_PREVIEW_MISMATCH",
|
|
4571
|
+
"Operator adjustment decision does not match its preview"
|
|
4572
|
+
);
|
|
4573
|
+
const proposedAt = parseIsoTimestamp(decision.proposedAt);
|
|
4574
|
+
const decidedAt = parseIsoTimestamp(decision.decidedAt);
|
|
4575
|
+
economyAssert(
|
|
4576
|
+
decision.proposedByAccountId === proposal.proposedByAccountId && proposedAt === parseIsoTimestamp(proposal.proposedAt) && decidedAt >= proposedAt,
|
|
4577
|
+
"INVALID_TIME_WINDOW",
|
|
4578
|
+
"Operator adjustment decision times are inconsistent"
|
|
4579
|
+
);
|
|
4580
|
+
economyAssert(
|
|
4581
|
+
decidedAt <= parseIsoTimestamp(preview.expiresAt),
|
|
4582
|
+
"ADJUSTMENT_EXPIRED",
|
|
4583
|
+
"Operator adjustment preview has expired"
|
|
4584
|
+
);
|
|
4585
|
+
}
|
|
4586
|
+
function canonicalOperatorAdjustmentDecisionPayload(decision) {
|
|
4587
|
+
assertExactKeys3(decision, DECISION_KEYS, "Operator adjustment decision");
|
|
4588
|
+
return JSON.stringify({
|
|
4589
|
+
schemaVersion: decision.schemaVersion,
|
|
4590
|
+
decisionId: decision.decisionId,
|
|
4591
|
+
adjustmentId: decision.adjustmentId,
|
|
4592
|
+
proposalId: decision.proposalId,
|
|
4593
|
+
proposalHash: decision.proposalHash,
|
|
4594
|
+
previewHash: decision.previewHash,
|
|
4595
|
+
decision: decision.decision,
|
|
4596
|
+
proposedByAccountId: decision.proposedByAccountId,
|
|
4597
|
+
decidedByAccountId: decision.decidedByAccountId,
|
|
4598
|
+
proposedAt: decision.proposedAt,
|
|
4599
|
+
decidedAt: decision.decidedAt
|
|
4600
|
+
});
|
|
4601
|
+
}
|
|
4602
|
+
function assertOperatorAdjustmentExecution(execution, preview, proposal, decision, expectedPreviewHash, expectedProposalHash, expectedDecisionHash) {
|
|
4603
|
+
assertOperatorAdjustmentDecision(
|
|
4604
|
+
decision,
|
|
4605
|
+
proposal,
|
|
4606
|
+
preview,
|
|
4607
|
+
expectedPreviewHash,
|
|
4608
|
+
expectedProposalHash
|
|
4609
|
+
);
|
|
4610
|
+
assertCanonicalHash6(expectedDecisionHash, "expectedDecisionHash");
|
|
4611
|
+
assertExactKeys3(execution, EXECUTION_KEYS, "Operator adjustment execution");
|
|
4612
|
+
economyAssert(
|
|
4613
|
+
execution.schemaVersion === ECONOMY_CONTRACT_VERSION,
|
|
4614
|
+
"INVALID_CONTRACT",
|
|
4615
|
+
"Unsupported operator adjustment execution"
|
|
4616
|
+
);
|
|
4617
|
+
assertEconomyIdentifier(execution.executionId, "executionId");
|
|
4618
|
+
assertEconomyIdentifier(execution.adjustmentId, "adjustmentId");
|
|
4619
|
+
assertCanonicalHash6(execution.previewHash, "previewHash");
|
|
4620
|
+
assertCanonicalHash6(execution.proposalHash, "proposalHash");
|
|
4621
|
+
assertCanonicalHash6(execution.decisionHash, "decisionHash");
|
|
4622
|
+
assertEconomyIdentifier(execution.sourceLotId, "sourceLotId");
|
|
4623
|
+
assertEconomyIdentifier(execution.transactionId, "transactionId");
|
|
4624
|
+
assertEconomyIdentifier(execution.resultReceiptId, "resultReceiptId");
|
|
4625
|
+
economyAssert(
|
|
4626
|
+
decision.decision === "approve",
|
|
4627
|
+
"ADJUSTMENT_NOT_APPROVED",
|
|
4628
|
+
"Only an approved adjustment may execute"
|
|
4629
|
+
);
|
|
4630
|
+
economyAssert(
|
|
4631
|
+
execution.adjustmentId === preview.adjustmentId && execution.previewHash === expectedPreviewHash && execution.proposalHash === expectedProposalHash && execution.decisionHash === expectedDecisionHash && execution.sourceLotId === preview.sourceLotId,
|
|
4632
|
+
"ADJUSTMENT_PREVIEW_MISMATCH",
|
|
4633
|
+
"Operator adjustment execution does not match its approval plan"
|
|
4634
|
+
);
|
|
4635
|
+
economyAssert(
|
|
4636
|
+
parseIsoTimestamp(execution.executedAt) >= parseIsoTimestamp(decision.decidedAt),
|
|
4637
|
+
"INVALID_TIME_WINDOW",
|
|
4638
|
+
"Operator adjustment execution predates its decision"
|
|
4639
|
+
);
|
|
4640
|
+
}
|
|
4641
|
+
function canonicalOperatorAdjustmentExecutionPayload(execution) {
|
|
4642
|
+
assertExactKeys3(execution, EXECUTION_KEYS, "Operator adjustment execution");
|
|
4643
|
+
return JSON.stringify({
|
|
4644
|
+
schemaVersion: execution.schemaVersion,
|
|
4645
|
+
executionId: execution.executionId,
|
|
4646
|
+
adjustmentId: execution.adjustmentId,
|
|
4647
|
+
previewHash: execution.previewHash,
|
|
4648
|
+
proposalHash: execution.proposalHash,
|
|
4649
|
+
decisionHash: execution.decisionHash,
|
|
4650
|
+
sourceLotId: execution.sourceLotId,
|
|
4651
|
+
transactionId: execution.transactionId,
|
|
4652
|
+
resultReceiptId: execution.resultReceiptId,
|
|
4653
|
+
executedAt: execution.executedAt
|
|
4654
|
+
});
|
|
4655
|
+
}
|
|
4656
|
+
|
|
4305
4657
|
// src/paid-lots.ts
|
|
4306
4658
|
var ZERO_ARITHMETIC = Object.freeze({
|
|
4307
4659
|
retainedDelta: serializeTokenSubunits(0n),
|
|
@@ -6842,7 +7194,7 @@ var PORTABLE_KEYS = /* @__PURE__ */ new Set([
|
|
|
6842
7194
|
"signature",
|
|
6843
7195
|
...PORTABLE_BODY_KEYS
|
|
6844
7196
|
]);
|
|
6845
|
-
function
|
|
7197
|
+
function assertExactKeys4(value, allowedKeys, label) {
|
|
6846
7198
|
economyAssert(
|
|
6847
7199
|
value !== null && typeof value === "object" && !Array.isArray(value),
|
|
6848
7200
|
"INVALID_CONTRACT",
|
|
@@ -6854,7 +7206,7 @@ function assertExactKeys3(value, allowedKeys, label) {
|
|
|
6854
7206
|
`${label} contains an unsupported field`
|
|
6855
7207
|
);
|
|
6856
7208
|
}
|
|
6857
|
-
function
|
|
7209
|
+
function assertCanonicalHash7(value, label) {
|
|
6858
7210
|
economyAssert(
|
|
6859
7211
|
typeof value === "string" && CANONICAL_HASH.test(value),
|
|
6860
7212
|
"INVALID_CONTRACT",
|
|
@@ -6863,7 +7215,7 @@ function assertCanonicalHash6(value, label) {
|
|
|
6863
7215
|
}
|
|
6864
7216
|
function canonicalHash(payload, hashCanonicalPayload2, label) {
|
|
6865
7217
|
const value = hashCanonicalPayload2(payload);
|
|
6866
|
-
|
|
7218
|
+
assertCanonicalHash7(value, label);
|
|
6867
7219
|
return value;
|
|
6868
7220
|
}
|
|
6869
7221
|
function assertUnsignedInteger(value, label) {
|
|
@@ -6931,7 +7283,7 @@ function canonicalSignatureMetadata(signature) {
|
|
|
6931
7283
|
};
|
|
6932
7284
|
}
|
|
6933
7285
|
function assertEconomySealedRecoveryPayload(payload) {
|
|
6934
|
-
|
|
7286
|
+
assertExactKeys4(
|
|
6935
7287
|
payload,
|
|
6936
7288
|
/* @__PURE__ */ new Set([
|
|
6937
7289
|
"schemaVersion",
|
|
@@ -6961,17 +7313,17 @@ function assertEconomySealedRecoveryPayload(payload) {
|
|
|
6961
7313
|
22,
|
|
6962
7314
|
22
|
|
6963
7315
|
);
|
|
6964
|
-
|
|
7316
|
+
assertCanonicalHash7(
|
|
6965
7317
|
payload.plaintextContentHash,
|
|
6966
7318
|
"Recovery plaintext-content hash"
|
|
6967
7319
|
);
|
|
6968
|
-
|
|
7320
|
+
assertCanonicalHash7(
|
|
6969
7321
|
payload.encryptionContextHash,
|
|
6970
7322
|
"Recovery encryption-context hash"
|
|
6971
7323
|
);
|
|
6972
7324
|
}
|
|
6973
7325
|
function assertAcceptanceBody(body) {
|
|
6974
|
-
|
|
7326
|
+
assertExactKeys4(
|
|
6975
7327
|
body,
|
|
6976
7328
|
"acceptanceEnvelopeId" in body ? ACCEPTANCE_KEYS : ACCEPTANCE_BODY_KEYS,
|
|
6977
7329
|
"Recovery acceptance body"
|
|
@@ -6990,9 +7342,9 @@ function assertAcceptanceBody(body) {
|
|
|
6990
7342
|
body.idempotencyFingerprint,
|
|
6991
7343
|
"economy.idempotency-key.v1"
|
|
6992
7344
|
);
|
|
6993
|
-
|
|
7345
|
+
assertCanonicalHash7(body.commandEnvelopeHash, "Command-envelope hash");
|
|
6994
7346
|
assertEconomyIdentifier(body.acceptedReceiptId, "acceptedReceiptId");
|
|
6995
|
-
|
|
7347
|
+
assertCanonicalHash7(body.acceptedReceiptHash, "Accepted-receipt hash");
|
|
6996
7348
|
assertEconomySealedRecoveryPayload(body.sealedPayload);
|
|
6997
7349
|
const preparedAt = parseIsoTimestamp(body.preparedAt);
|
|
6998
7350
|
const acceptedAt = parseIsoTimestamp(body.acceptedAt);
|
|
@@ -7040,7 +7392,7 @@ function createEconomyRecoveryAcceptanceEnvelope(body, hashCanonicalPayload2) {
|
|
|
7040
7392
|
};
|
|
7041
7393
|
}
|
|
7042
7394
|
function assertEconomyRecoveryAcceptanceEnvelope(envelope, hashCanonicalPayload2) {
|
|
7043
|
-
|
|
7395
|
+
assertExactKeys4(envelope, ACCEPTANCE_KEYS, "Recovery acceptance envelope");
|
|
7044
7396
|
assertAcceptanceBody(envelope);
|
|
7045
7397
|
assertEconomyIdentifier(
|
|
7046
7398
|
envelope.acceptanceEnvelopeId,
|
|
@@ -7081,7 +7433,7 @@ function canonicalEconomyRecoveryAcceptanceEnvelopePayload(envelope, hashCanonic
|
|
|
7081
7433
|
});
|
|
7082
7434
|
}
|
|
7083
7435
|
function assertCommittedResultBody(body) {
|
|
7084
|
-
|
|
7436
|
+
assertExactKeys4(
|
|
7085
7437
|
body,
|
|
7086
7438
|
"committedResultId" in body ? COMMITTED_RESULT_KEYS : COMMITTED_RESULT_BODY_KEYS,
|
|
7087
7439
|
"Recovery committed-result body"
|
|
@@ -7109,7 +7461,7 @@ function assertCommittedResultBody(body) {
|
|
|
7109
7461
|
[body.authorityCommitHash, "Authority-commit hash"],
|
|
7110
7462
|
[body.authorityHeadHashAfter, "Authority-head hash"]
|
|
7111
7463
|
]) {
|
|
7112
|
-
|
|
7464
|
+
assertCanonicalHash7(value, label);
|
|
7113
7465
|
}
|
|
7114
7466
|
economyAssert(
|
|
7115
7467
|
RESULT_OUTCOMES.has(body.outcome),
|
|
@@ -7132,7 +7484,7 @@ function assertCommittedResultBody(body) {
|
|
|
7132
7484
|
assertEconomyIdentifier(body.transactionId, "transactionId");
|
|
7133
7485
|
}
|
|
7134
7486
|
if (body.transactionCanonicalHash !== void 0) {
|
|
7135
|
-
|
|
7487
|
+
assertCanonicalHash7(
|
|
7136
7488
|
body.transactionCanonicalHash,
|
|
7137
7489
|
"Transaction canonical hash"
|
|
7138
7490
|
);
|
|
@@ -7175,7 +7527,7 @@ function createEconomyRecoveryCommittedResult(body, hashCanonicalPayload2) {
|
|
|
7175
7527
|
};
|
|
7176
7528
|
}
|
|
7177
7529
|
function assertEconomyRecoveryCommittedResult(result, hashCanonicalPayload2) {
|
|
7178
|
-
|
|
7530
|
+
assertExactKeys4(
|
|
7179
7531
|
result,
|
|
7180
7532
|
COMMITTED_RESULT_KEYS,
|
|
7181
7533
|
"Recovery committed result"
|
|
@@ -7234,7 +7586,7 @@ function assertEconomyRecoveryResultLink(acceptance, result, hashCanonicalPayloa
|
|
|
7234
7586
|
);
|
|
7235
7587
|
}
|
|
7236
7588
|
function assertEconomyEvidenceSignatureMetadata(signature) {
|
|
7237
|
-
|
|
7589
|
+
assertExactKeys4(
|
|
7238
7590
|
signature,
|
|
7239
7591
|
/* @__PURE__ */ new Set([
|
|
7240
7592
|
"schemaVersion",
|
|
@@ -7254,7 +7606,7 @@ function assertEconomyEvidenceSignatureMetadata(signature) {
|
|
|
7254
7606
|
parseIsoTimestamp(signature.signedAt);
|
|
7255
7607
|
}
|
|
7256
7608
|
function assertEconomyEvidenceSignature(signature) {
|
|
7257
|
-
|
|
7609
|
+
assertExactKeys4(
|
|
7258
7610
|
signature,
|
|
7259
7611
|
/* @__PURE__ */ new Set([
|
|
7260
7612
|
"schemaVersion",
|
|
@@ -7276,7 +7628,7 @@ function assertEconomyEvidenceSignature(signature) {
|
|
|
7276
7628
|
assertBase64url(signature.value, "Evidence signature value", 32, 2048);
|
|
7277
7629
|
}
|
|
7278
7630
|
function assertRegionalEvidenceBody(body) {
|
|
7279
|
-
|
|
7631
|
+
assertExactKeys4(
|
|
7280
7632
|
body,
|
|
7281
7633
|
"evidenceReceiptId" in body ? REGIONAL_KEYS : REGIONAL_BODY_KEYS,
|
|
7282
7634
|
"Regional evidence-receipt body"
|
|
@@ -7308,7 +7660,7 @@ function assertRegionalEvidenceBody(body) {
|
|
|
7308
7660
|
"INVALID_CONTRACT",
|
|
7309
7661
|
"Unsupported recovery record kind"
|
|
7310
7662
|
);
|
|
7311
|
-
|
|
7663
|
+
assertCanonicalHash7(
|
|
7312
7664
|
body.recoveryRecordContentHash,
|
|
7313
7665
|
"Recovery-record content hash"
|
|
7314
7666
|
);
|
|
@@ -7324,7 +7676,7 @@ function assertRegionalEvidenceBody(body) {
|
|
|
7324
7676
|
"INVALID_CONTRACT",
|
|
7325
7677
|
"Non-genesis regional evidence receipt requires a previous hash"
|
|
7326
7678
|
);
|
|
7327
|
-
|
|
7679
|
+
assertCanonicalHash7(
|
|
7328
7680
|
body.previousReceiptHash,
|
|
7329
7681
|
"Previous evidence-receipt hash"
|
|
7330
7682
|
);
|
|
@@ -7368,7 +7720,7 @@ function createEconomyRegionalEvidenceReceipt(body, signature, hashCanonicalPayl
|
|
|
7368
7720
|
};
|
|
7369
7721
|
}
|
|
7370
7722
|
function assertEconomyRegionalEvidenceReceipt(receipt, hashCanonicalPayload2) {
|
|
7371
|
-
|
|
7723
|
+
assertExactKeys4(receipt, REGIONAL_KEYS, "Regional evidence receipt");
|
|
7372
7724
|
assertRegionalEvidenceBody(receipt);
|
|
7373
7725
|
assertEconomyIdentifier(receipt.evidenceReceiptId, "evidenceReceiptId");
|
|
7374
7726
|
assertEconomyEvidenceSignature(receipt.signature);
|
|
@@ -7499,7 +7851,7 @@ function assertEconomyRegionalEvidenceChain(receipts, expectedPreviousReceiptHas
|
|
|
7499
7851
|
"INVALID_CONTRACT",
|
|
7500
7852
|
"Partial evidence chain requires its trusted preceding hash"
|
|
7501
7853
|
);
|
|
7502
|
-
|
|
7854
|
+
assertCanonicalHash7(
|
|
7503
7855
|
expectedPreviousReceiptHash,
|
|
7504
7856
|
"Expected preceding evidence-receipt hash"
|
|
7505
7857
|
);
|
|
@@ -7570,7 +7922,7 @@ function assertEconomyRegionalEvidenceEquality(receipts, expectedRegions, hashCa
|
|
|
7570
7922
|
);
|
|
7571
7923
|
}
|
|
7572
7924
|
function assertEconomyMerkleInclusionProof(proof) {
|
|
7573
|
-
|
|
7925
|
+
assertExactKeys4(
|
|
7574
7926
|
proof,
|
|
7575
7927
|
/* @__PURE__ */ new Set([
|
|
7576
7928
|
"schemaVersion",
|
|
@@ -7591,8 +7943,8 @@ function assertEconomyMerkleInclusionProof(proof) {
|
|
|
7591
7943
|
"Unsupported Merkle inclusion proof"
|
|
7592
7944
|
);
|
|
7593
7945
|
assertEconomyIdentifier(proof.anchorId, "anchorId");
|
|
7594
|
-
|
|
7595
|
-
|
|
7946
|
+
assertCanonicalHash7(proof.anchorManifestHash, "Anchor-manifest hash");
|
|
7947
|
+
assertCanonicalHash7(proof.leafHash, "Merkle leaf hash");
|
|
7596
7948
|
assertUnsignedInteger(proof.leafIndex, "Merkle leaf index");
|
|
7597
7949
|
assertUnsignedInteger(proof.leafCount, "Merkle leaf count");
|
|
7598
7950
|
economyAssert(
|
|
@@ -7601,7 +7953,7 @@ function assertEconomyMerkleInclusionProof(proof) {
|
|
|
7601
7953
|
"Merkle leaf position is outside its bounded tree"
|
|
7602
7954
|
);
|
|
7603
7955
|
for (const step of proof.siblings) {
|
|
7604
|
-
|
|
7956
|
+
assertExactKeys4(
|
|
7605
7957
|
step,
|
|
7606
7958
|
/* @__PURE__ */ new Set(["schemaVersion", "side", "hash"]),
|
|
7607
7959
|
"Merkle proof step"
|
|
@@ -7611,7 +7963,7 @@ function assertEconomyMerkleInclusionProof(proof) {
|
|
|
7611
7963
|
"INVALID_CONTRACT",
|
|
7612
7964
|
"Unsupported Merkle proof step"
|
|
7613
7965
|
);
|
|
7614
|
-
|
|
7966
|
+
assertCanonicalHash7(step.hash, "Merkle sibling hash");
|
|
7615
7967
|
}
|
|
7616
7968
|
}
|
|
7617
7969
|
function canonicalMerkleProof(proof) {
|
|
@@ -7690,7 +8042,7 @@ function assertEconomyMerkleInclusion(proof, anchor, hashCanonicalPayload2) {
|
|
|
7690
8042
|
);
|
|
7691
8043
|
}
|
|
7692
8044
|
function assertPortableEvidenceReference(reference) {
|
|
7693
|
-
|
|
8045
|
+
assertExactKeys4(
|
|
7694
8046
|
reference,
|
|
7695
8047
|
/* @__PURE__ */ new Set([
|
|
7696
8048
|
"schemaVersion",
|
|
@@ -7710,7 +8062,7 @@ function assertPortableEvidenceReference(reference) {
|
|
|
7710
8062
|
reference.evidenceReceiptId,
|
|
7711
8063
|
"evidenceReceiptId"
|
|
7712
8064
|
);
|
|
7713
|
-
|
|
8065
|
+
assertCanonicalHash7(
|
|
7714
8066
|
reference.evidenceReceiptHash,
|
|
7715
8067
|
"Evidence-receipt hash"
|
|
7716
8068
|
);
|
|
@@ -7727,7 +8079,7 @@ function canonicalPortableEvidenceReference(reference) {
|
|
|
7727
8079
|
};
|
|
7728
8080
|
}
|
|
7729
8081
|
function assertPortableBody(body) {
|
|
7730
|
-
|
|
8082
|
+
assertExactKeys4(
|
|
7731
8083
|
body,
|
|
7732
8084
|
"portableReceiptId" in body ? PORTABLE_KEYS : PORTABLE_BODY_KEYS,
|
|
7733
8085
|
"Portable customer-receipt body"
|
|
@@ -7766,7 +8118,7 @@ function assertPortableBody(body) {
|
|
|
7766
8118
|
[body.committedResultContentHash, "Committed-result content hash"],
|
|
7767
8119
|
[body.authorityCommitHash, "Authority-commit hash"]
|
|
7768
8120
|
]) {
|
|
7769
|
-
|
|
8121
|
+
assertCanonicalHash7(value, label);
|
|
7770
8122
|
}
|
|
7771
8123
|
assertUnsignedInteger(body.authoritySequence, "Authority sequence");
|
|
7772
8124
|
economyAssert(
|
|
@@ -7851,7 +8203,7 @@ function createEconomyPortableCustomerReceipt(body, signature, hashCanonicalPayl
|
|
|
7851
8203
|
};
|
|
7852
8204
|
}
|
|
7853
8205
|
function assertEconomyPortableCustomerReceipt(receipt, hashCanonicalPayload2) {
|
|
7854
|
-
|
|
8206
|
+
assertExactKeys4(receipt, PORTABLE_KEYS, "Portable customer receipt");
|
|
7855
8207
|
assertPortableBody(receipt);
|
|
7856
8208
|
assertEconomyIdentifier(receipt.portableReceiptId, "portableReceiptId");
|
|
7857
8209
|
assertEconomyEvidenceSignature(receipt.signature);
|
|
@@ -8111,6 +8463,241 @@ function assertSpendRequest(request) {
|
|
|
8111
8463
|
);
|
|
8112
8464
|
}
|
|
8113
8465
|
}
|
|
8466
|
+
|
|
8467
|
+
// src/wallet-initialization.ts
|
|
8468
|
+
var INITIALIZATION_IDENTITY_DOMAIN = "economy.personal-wallet-initialization.identity.v1";
|
|
8469
|
+
var ZERO_TOKEN_SUBUNITS = serializeTokenSubunits(0n);
|
|
8470
|
+
var STATE_KEYS = /* @__PURE__ */ new Set([
|
|
8471
|
+
"schemaVersion",
|
|
8472
|
+
"documentIds",
|
|
8473
|
+
"command",
|
|
8474
|
+
"wallet",
|
|
8475
|
+
"scope",
|
|
8476
|
+
"balance",
|
|
8477
|
+
"lifetime",
|
|
8478
|
+
"activityEntries",
|
|
8479
|
+
"outboxIntent"
|
|
8480
|
+
]);
|
|
8481
|
+
var COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
8482
|
+
"schemaVersion",
|
|
8483
|
+
"commandType",
|
|
8484
|
+
"walletKind",
|
|
8485
|
+
"subjectAccountId",
|
|
8486
|
+
"walletId",
|
|
8487
|
+
"portfolioId",
|
|
8488
|
+
"initializedAt"
|
|
8489
|
+
]);
|
|
8490
|
+
var OUTBOX_KEYS = /* @__PURE__ */ new Set([
|
|
8491
|
+
"schemaVersion",
|
|
8492
|
+
"eventType",
|
|
8493
|
+
"eventId",
|
|
8494
|
+
"subjectAccountId",
|
|
8495
|
+
"walletId",
|
|
8496
|
+
"portfolioId",
|
|
8497
|
+
"occurredAt"
|
|
8498
|
+
]);
|
|
8499
|
+
var DOCUMENT_ID_KEYS = /* @__PURE__ */ new Set([
|
|
8500
|
+
"walletDescriptorId",
|
|
8501
|
+
"accessProjectionId",
|
|
8502
|
+
"balanceProjectionId",
|
|
8503
|
+
"lifetimeProjectionId",
|
|
8504
|
+
"outboxEventId"
|
|
8505
|
+
]);
|
|
8506
|
+
function assertExactKeys5(value, allowed, label) {
|
|
8507
|
+
economyAssert(
|
|
8508
|
+
value !== null && typeof value === "object" && !Array.isArray(value),
|
|
8509
|
+
"INVALID_CONTRACT",
|
|
8510
|
+
`${label} must be an object`
|
|
8511
|
+
);
|
|
8512
|
+
economyAssert(
|
|
8513
|
+
Object.keys(value).every((key) => allowed.has(key)),
|
|
8514
|
+
"INVALID_CONTRACT",
|
|
8515
|
+
`${label} contains an unsupported field`
|
|
8516
|
+
);
|
|
8517
|
+
}
|
|
8518
|
+
function identityDigest(subjectAccountId, hash) {
|
|
8519
|
+
assertEconomyIdentifier(subjectAccountId, "subjectAccountId");
|
|
8520
|
+
const canonicalIdentity = JSON.stringify({
|
|
8521
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8522
|
+
domain: INITIALIZATION_IDENTITY_DOMAIN,
|
|
8523
|
+
subjectAccountId
|
|
8524
|
+
});
|
|
8525
|
+
const canonicalHash2 = hash(canonicalIdentity);
|
|
8526
|
+
economyAssert(
|
|
8527
|
+
/^sha256:[a-f0-9]{64}$/u.test(canonicalHash2),
|
|
8528
|
+
"INVALID_CONTRACT",
|
|
8529
|
+
"Wallet initialization identity hash must be canonical SHA-256"
|
|
8530
|
+
);
|
|
8531
|
+
return canonicalHash2.slice("sha256:".length);
|
|
8532
|
+
}
|
|
8533
|
+
function createPersonalWalletInitializationDocumentIds(subjectAccountId, hash) {
|
|
8534
|
+
const digest = identityDigest(subjectAccountId, hash);
|
|
8535
|
+
return {
|
|
8536
|
+
walletId: `wallet:personal:${digest}`,
|
|
8537
|
+
portfolioId: `portfolio:self:${digest}`,
|
|
8538
|
+
walletDescriptorId: `wallet-descriptor:${digest}`,
|
|
8539
|
+
accessProjectionId: `wallet-access:${digest}`,
|
|
8540
|
+
balanceProjectionId: `wallet-balance:${digest}`,
|
|
8541
|
+
lifetimeProjectionId: `wallet-lifetime:${digest}`,
|
|
8542
|
+
outboxEventId: `outbox:wallet-initialized:${digest}`
|
|
8543
|
+
};
|
|
8544
|
+
}
|
|
8545
|
+
function assertPersonalWalletInitializationCommand(command) {
|
|
8546
|
+
assertExactKeys5(command, COMMAND_KEYS, "Wallet initialization command");
|
|
8547
|
+
economyAssert(
|
|
8548
|
+
command.schemaVersion === ECONOMY_CONTRACT_VERSION && command.commandType === "initialize-wallet" && command.walletKind === "personal",
|
|
8549
|
+
"INVALID_CONTRACT",
|
|
8550
|
+
"Unsupported personal-wallet initialization command"
|
|
8551
|
+
);
|
|
8552
|
+
assertEconomyIdentifier(command.subjectAccountId, "subjectAccountId");
|
|
8553
|
+
assertEconomyIdentifier(command.walletId, "walletId");
|
|
8554
|
+
assertEconomyIdentifier(command.portfolioId, "portfolioId");
|
|
8555
|
+
parseIsoTimestamp(command.initializedAt);
|
|
8556
|
+
}
|
|
8557
|
+
function canonicalPersonalWalletInitializationCommandPayload(command) {
|
|
8558
|
+
assertPersonalWalletInitializationCommand(command);
|
|
8559
|
+
return JSON.stringify({
|
|
8560
|
+
schemaVersion: command.schemaVersion,
|
|
8561
|
+
commandType: command.commandType,
|
|
8562
|
+
walletKind: command.walletKind,
|
|
8563
|
+
subjectAccountId: command.subjectAccountId,
|
|
8564
|
+
walletId: command.walletId,
|
|
8565
|
+
portfolioId: command.portfolioId,
|
|
8566
|
+
initializedAt: command.initializedAt
|
|
8567
|
+
});
|
|
8568
|
+
}
|
|
8569
|
+
function assertPersonalWalletInitializationOutboxIntent(intent) {
|
|
8570
|
+
assertExactKeys5(intent, OUTBOX_KEYS, "Wallet initialization outbox intent");
|
|
8571
|
+
economyAssert(
|
|
8572
|
+
intent.schemaVersion === ECONOMY_CONTRACT_VERSION && intent.eventType === "wallet.initialized.v1",
|
|
8573
|
+
"INVALID_CONTRACT",
|
|
8574
|
+
"Unsupported wallet initialization outbox intent"
|
|
8575
|
+
);
|
|
8576
|
+
assertEconomyIdentifier(intent.eventId, "eventId");
|
|
8577
|
+
assertEconomyIdentifier(intent.subjectAccountId, "subjectAccountId");
|
|
8578
|
+
assertEconomyIdentifier(intent.walletId, "walletId");
|
|
8579
|
+
assertEconomyIdentifier(intent.portfolioId, "portfolioId");
|
|
8580
|
+
parseIsoTimestamp(intent.occurredAt);
|
|
8581
|
+
}
|
|
8582
|
+
function canonicalPersonalWalletInitializationOutboxPayload(intent) {
|
|
8583
|
+
assertPersonalWalletInitializationOutboxIntent(intent);
|
|
8584
|
+
return JSON.stringify({
|
|
8585
|
+
schemaVersion: intent.schemaVersion,
|
|
8586
|
+
eventType: intent.eventType,
|
|
8587
|
+
eventId: intent.eventId,
|
|
8588
|
+
subjectAccountId: intent.subjectAccountId,
|
|
8589
|
+
walletId: intent.walletId,
|
|
8590
|
+
portfolioId: intent.portfolioId,
|
|
8591
|
+
occurredAt: intent.occurredAt
|
|
8592
|
+
});
|
|
8593
|
+
}
|
|
8594
|
+
function createPersonalWalletInitializationState(input, hash) {
|
|
8595
|
+
parseIsoTimestamp(input.initializedAt);
|
|
8596
|
+
const { walletId, portfolioId, ...documentIds } = createPersonalWalletInitializationDocumentIds(
|
|
8597
|
+
input.subjectAccountId,
|
|
8598
|
+
hash
|
|
8599
|
+
);
|
|
8600
|
+
const command = {
|
|
8601
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8602
|
+
commandType: "initialize-wallet",
|
|
8603
|
+
walletKind: "personal",
|
|
8604
|
+
subjectAccountId: input.subjectAccountId,
|
|
8605
|
+
walletId,
|
|
8606
|
+
portfolioId,
|
|
8607
|
+
initializedAt: input.initializedAt
|
|
8608
|
+
};
|
|
8609
|
+
const state = {
|
|
8610
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8611
|
+
documentIds,
|
|
8612
|
+
command,
|
|
8613
|
+
wallet: {
|
|
8614
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8615
|
+
walletId,
|
|
8616
|
+
accountId: input.subjectAccountId,
|
|
8617
|
+
kind: "personal",
|
|
8618
|
+
ownerType: "account",
|
|
8619
|
+
ownerId: input.subjectAccountId,
|
|
8620
|
+
status: "active",
|
|
8621
|
+
version: 1,
|
|
8622
|
+
createdAt: input.initializedAt
|
|
8623
|
+
},
|
|
8624
|
+
scope: {
|
|
8625
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8626
|
+
portfolioId,
|
|
8627
|
+
subjectAccountId: input.subjectAccountId,
|
|
8628
|
+
components: [{ walletId, role: "personal" }]
|
|
8629
|
+
},
|
|
8630
|
+
balance: {
|
|
8631
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8632
|
+
walletId,
|
|
8633
|
+
available: ZERO_TOKEN_SUBUNITS,
|
|
8634
|
+
reserved: ZERO_TOKEN_SUBUNITS,
|
|
8635
|
+
held: ZERO_TOKEN_SUBUNITS,
|
|
8636
|
+
rewardProgress: ZERO_TOKEN_SUBUNITS,
|
|
8637
|
+
version: 1,
|
|
8638
|
+
asOf: input.initializedAt
|
|
8639
|
+
},
|
|
8640
|
+
lifetime: {
|
|
8641
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8642
|
+
walletId,
|
|
8643
|
+
totals: {
|
|
8644
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8645
|
+
bought: ZERO_TOKEN_SUBUNITS,
|
|
8646
|
+
earned: ZERO_TOKEN_SUBUNITS,
|
|
8647
|
+
allocated: ZERO_TOKEN_SUBUNITS,
|
|
8648
|
+
reclaimed: ZERO_TOKEN_SUBUNITS,
|
|
8649
|
+
spent: ZERO_TOKEN_SUBUNITS,
|
|
8650
|
+
reversed: ZERO_TOKEN_SUBUNITS
|
|
8651
|
+
},
|
|
8652
|
+
version: 1,
|
|
8653
|
+
asOf: input.initializedAt
|
|
8654
|
+
},
|
|
8655
|
+
activityEntries: [],
|
|
8656
|
+
outboxIntent: {
|
|
8657
|
+
schemaVersion: ECONOMY_CONTRACT_VERSION,
|
|
8658
|
+
eventType: "wallet.initialized.v1",
|
|
8659
|
+
eventId: documentIds.outboxEventId,
|
|
8660
|
+
subjectAccountId: input.subjectAccountId,
|
|
8661
|
+
walletId,
|
|
8662
|
+
portfolioId,
|
|
8663
|
+
occurredAt: input.initializedAt
|
|
8664
|
+
}
|
|
8665
|
+
};
|
|
8666
|
+
assertPersonalWalletInitializationState(state);
|
|
8667
|
+
return state;
|
|
8668
|
+
}
|
|
8669
|
+
function assertPersonalWalletInitializationState(state) {
|
|
8670
|
+
assertExactKeys5(state, STATE_KEYS, "Wallet initialization state");
|
|
8671
|
+
assertExactKeys5(
|
|
8672
|
+
state.documentIds,
|
|
8673
|
+
DOCUMENT_ID_KEYS,
|
|
8674
|
+
"Wallet initialization document IDs"
|
|
8675
|
+
);
|
|
8676
|
+
economyAssert(
|
|
8677
|
+
state.schemaVersion === ECONOMY_CONTRACT_VERSION,
|
|
8678
|
+
"INVALID_CONTRACT",
|
|
8679
|
+
"Unsupported wallet initialization state"
|
|
8680
|
+
);
|
|
8681
|
+
for (const identifier of Object.values(state.documentIds)) {
|
|
8682
|
+
assertEconomyIdentifier(identifier, "wallet initialization document ID");
|
|
8683
|
+
}
|
|
8684
|
+
economyAssert(
|
|
8685
|
+
new Set(Object.values(state.documentIds)).size === Object.values(state.documentIds).length,
|
|
8686
|
+
"INVALID_CONTRACT",
|
|
8687
|
+
"Wallet initialization document IDs must be unique"
|
|
8688
|
+
);
|
|
8689
|
+
assertPersonalWalletInitializationCommand(state.command);
|
|
8690
|
+
assertWallet(state.wallet);
|
|
8691
|
+
assertWalletPortfolioReadScope(state.scope);
|
|
8692
|
+
assertWalletBalanceSummary(state.balance);
|
|
8693
|
+
assertWalletLifetimeSnapshot(state.lifetime);
|
|
8694
|
+
assertPersonalWalletInitializationOutboxIntent(state.outboxIntent);
|
|
8695
|
+
economyAssert(
|
|
8696
|
+
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,
|
|
8697
|
+
"INVALID_CONTRACT",
|
|
8698
|
+
"Personal-wallet initialization state is incomplete or inconsistent"
|
|
8699
|
+
);
|
|
8700
|
+
}
|
|
8114
8701
|
export {
|
|
8115
8702
|
BASELINE_GBP_CATALOG_VERSION,
|
|
8116
8703
|
BASELINE_GBP_REFERENCE_RATE,
|
|
@@ -8192,9 +8779,16 @@ export {
|
|
|
8192
8779
|
assertModuleSpendQuote,
|
|
8193
8780
|
assertNonNegativeAccounts,
|
|
8194
8781
|
assertOpenPurchaseIntent,
|
|
8782
|
+
assertOperatorAdjustmentDecision,
|
|
8783
|
+
assertOperatorAdjustmentExecution,
|
|
8784
|
+
assertOperatorAdjustmentPreview,
|
|
8785
|
+
assertOperatorAdjustmentProposal,
|
|
8195
8786
|
assertPaidLotLifecycle,
|
|
8196
8787
|
assertPaidLotLifecycleEvent,
|
|
8197
8788
|
assertPaidLotPurchaseProvenance,
|
|
8789
|
+
assertPersonalWalletInitializationCommand,
|
|
8790
|
+
assertPersonalWalletInitializationOutboxIntent,
|
|
8791
|
+
assertPersonalWalletInitializationState,
|
|
8198
8792
|
assertPurchaseCapReservation,
|
|
8199
8793
|
assertPurchaseCapReservationTransition,
|
|
8200
8794
|
assertPurchaseIntentBinding,
|
|
@@ -8252,6 +8846,12 @@ export {
|
|
|
8252
8846
|
canonicalEconomyRegionalEvidenceReceiptBodyPayload,
|
|
8253
8847
|
canonicalEconomyRegionalEvidenceReceiptPayload,
|
|
8254
8848
|
canonicalEconomyRegionalEvidenceReceiptSigningPayload,
|
|
8849
|
+
canonicalOperatorAdjustmentDecisionPayload,
|
|
8850
|
+
canonicalOperatorAdjustmentExecutionPayload,
|
|
8851
|
+
canonicalOperatorAdjustmentPreviewPayload,
|
|
8852
|
+
canonicalOperatorAdjustmentProposalPayload,
|
|
8853
|
+
canonicalPersonalWalletInitializationCommandPayload,
|
|
8854
|
+
canonicalPersonalWalletInitializationOutboxPayload,
|
|
8255
8855
|
canonicalTransactionPayload,
|
|
8256
8856
|
closeModuleAllowance,
|
|
8257
8857
|
convertRewardPayout,
|
|
@@ -8267,6 +8867,8 @@ export {
|
|
|
8267
8867
|
createModuleSpendHold,
|
|
8268
8868
|
createModuleSpendQuote,
|
|
8269
8869
|
createPaidLotLifecycle,
|
|
8870
|
+
createPersonalWalletInitializationDocumentIds,
|
|
8871
|
+
createPersonalWalletInitializationState,
|
|
8270
8872
|
createProjectionSnapshot,
|
|
8271
8873
|
createPurchaseIntentLifecycle,
|
|
8272
8874
|
createReversalTransaction,
|