@hyperscale0/hsx 5.0.0 → 5.1.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/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const HSX_VERSION = "5.0.0";
1
+ export const HSX_VERSION = "5.1.0";
2
2
  export const HSX_TARGET_UDL_VERSION = 4;
package/std/cards.hsx CHANGED
@@ -28,11 +28,13 @@ instrument authorization(card: ref<cards.card>, merchant: party, issuer: party =
28
28
  lifecycle { states: [pending, approved, captured, declined, reversed, expired], initial: pending }
29
29
  action create {
30
30
  requires self.card in [active]
31
+ requires self.card.holder in [active]
31
32
  requires self.amount <= self.card.spendLimit
32
33
  }
33
34
  action approve {
34
35
  from: pending, to: approved, actor: { party: issuer }, deadline: { at: self.expiresAt }
35
36
  requires self.card in [active]
37
+ requires self.card.holder in [active]
36
38
  moves reserve self.amount from self.card.holder.holder to merchant capture "reservation"
37
39
  }
38
40
  action capture { from: approved, to: captured, actor: { party: merchant }, deadline: { at: self.expiresAt }, moves post self.reservation }
package/std/financing.hsx CHANGED
@@ -525,7 +525,7 @@ instrument late_charge(on: ref<financing.installments>[], grace: duration = 3d,
525
525
  }
526
526
  lifecycle { states: [proposed, assessed, collected, waived, refunded], initial: proposed }
527
527
  action create { calculate: [{ target: overdueAt, op: shift, date: { field: self.assessment.overdueAt }, milliseconds: { literal: 0 }, direction: after }], requires unique "recovery_assessment" on [self.assessment]; requires self.plan == self.assessment.plan }
528
- action assess {
528
+ action assess { allowZero: true,
529
529
  from: proposed, to: assessed, actor: clock, due: { at: self.assessment.overdueAt }
530
530
  requires self.assessment.slice.principalReceivable.balance > "0"
531
531
  moves self.amount from self.debt to self.receivable
package/std/lending.hsx CHANGED
@@ -25,14 +25,15 @@ instrument round(borrower: party, plan: ref<financing.installments> = object(fin
25
25
 
26
26
  instrument commitment(round: ref<lending.round>, wallet: ref<wallet.balance>, investor: party = party(person)) {
27
27
  summary: "One investor's original-wallet contribution, capped cumulatively within the round."
28
- fields { round: ref<round>, wallet: ref<wallet>, amount: money, loss: account(investor, claim, "loss") }
28
+ fields { round: ref<round>, wallet: ref<wallet>, investor: account of investor, amount: money, loss: account(investor, claim, "loss") }
29
29
  lifecycle { states: [committed, funded, withdrawn, refunded], initial: committed }
30
- invariants sum "amount" of { instrument: all(lending.commitment), reference: "round", anchor: self.round, states: [committed, funded], limit: 366, where: { wallet: { field: self.wallet } } } <= self.round.maximumTicket
30
+ invariants sum "amount" of { instrument: all(lending.commitment), reference: "round", anchor: self.round, states: [committed, funded], limit: 366, where: { investor: { field: self.investor } } } <= self.round.maximumTicket
31
31
  invariants sum "amount" of { instrument: all(lending.commitment), reference: "round", anchor: self.round, states: [committed, funded], limit: 366 } <= self.round.price
32
32
  action create {
33
33
  actor: { party: investor }
34
34
  requires self.round in [open]
35
35
  requires self.wallet in [active]
36
+ requires self.wallet.holder == self.investor
36
37
  requires self.amount >= self.round.minimumTicket
37
38
  deadline: { at: self.round.closesAt }
38
39
  moves self.amount from self.wallet.held to self.round.held
package/std/money.hsx CHANGED
@@ -97,6 +97,7 @@ instrument pool(payer: party, payee: party, target: money, closes: date) {
97
97
  contribution: {
98
98
  fields { pool: ref<parent>, payer: account of payer, amount: money, remaining: money? }
99
99
  lifecycle { states: [pending, paid, refunded], initial: pending }
100
+ invariants count of { instrument: current(), reference: "pool", anchor: self.pool, states: [paid], limit: 366 } <= 366
100
101
  action create { requires self.pool in [open] }
101
102
  action pay { from: pending, to: paid, actor: { party: payer }, deadline: { at: self.pool.closesAt }, requires self.pool in [open], calculate: [{ target: remaining, op: subtract, base: { field: self.pool.target }, subtract: [{ field: self.pool.held.balance }] }], requires self.amount <= self.remaining, moves self.amount from self.payer to self.pool.held }
102
103
  action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from self.pool.held to self.payer }
package/std/reporting.hsx CHANGED
@@ -117,6 +117,12 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
117
117
  type: { kind: "money", currency: "SAR" },
118
118
  required: true
119
119
  },
120
+ {
121
+ name: "earnedProfit",
122
+ field: "profitEarned.balance",
123
+ type: { kind: "money", currency: "SAR" },
124
+ required: true
125
+ },
120
126
  {
121
127
  name: "scheduledPrincipal",
122
128
  field: "principal",
@@ -139,7 +145,8 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
139
145
  },
140
146
  { id: "observed", op: "parameter", name: "observationAt" },
141
147
  { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
142
- { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
148
+ { id: "totalOutstanding", op: "sum", left: "scheduledOutstanding", right: "earnedProfit" },
149
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "totalOutstanding" },
143
150
  { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
144
151
  { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
145
152
  { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
@@ -464,6 +471,12 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
464
471
  type: { kind: "money", currency: "SAR" },
465
472
  required: true
466
473
  },
474
+ {
475
+ name: "earnedProfit",
476
+ field: "profitEarned.balance",
477
+ type: { kind: "money", currency: "SAR" },
478
+ required: true
479
+ },
467
480
  {
468
481
  name: "scheduledPrincipal",
469
482
  field: "principal",
@@ -486,7 +499,8 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
486
499
  },
487
500
  { id: "observed", op: "parameter", name: "observationAt" },
488
501
  { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
489
- { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
502
+ { id: "totalOutstanding", op: "sum", left: "scheduledOutstanding", right: "earnedProfit" },
503
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "totalOutstanding" },
490
504
  { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
491
505
  { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
492
506
  { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
@@ -744,6 +758,12 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
744
758
  type: { kind: "money", currency: "SAR" },
745
759
  required: true
746
760
  },
761
+ {
762
+ name: "earnedProfit",
763
+ field: "profitEarned.balance",
764
+ type: { kind: "money", currency: "SAR" },
765
+ required: true
766
+ },
747
767
  {
748
768
  name: "scheduledPrincipal",
749
769
  field: "principal",
@@ -766,7 +786,8 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
766
786
  },
767
787
  { id: "observed", op: "parameter", name: "observationAt" },
768
788
  { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
769
- { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
789
+ { id: "totalOutstanding", op: "sum", left: "scheduledOutstanding", right: "earnedProfit" },
790
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "totalOutstanding" },
770
791
  { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
771
792
  { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
772
793
  { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }
@@ -1113,6 +1134,12 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
1113
1134
  type: { kind: "money", currency: "SAR" },
1114
1135
  required: true
1115
1136
  },
1137
+ {
1138
+ name: "earnedProfit",
1139
+ field: "profitEarned.balance",
1140
+ type: { kind: "money", currency: "SAR" },
1141
+ required: true
1142
+ },
1116
1143
  {
1117
1144
  name: "scheduledPrincipal",
1118
1145
  field: "principal",
@@ -1135,7 +1162,8 @@ instrument portfolio(on: ref<financing.installments>[], default_days: integer(1,
1135
1162
  },
1136
1163
  { id: "observed", op: "parameter", name: "observationAt" },
1137
1164
  { id: "scheduledOutstanding", op: "sum", left: "principal", right: "profit" },
1138
- { id: "unpaid", op: "less", left: "zeroMoney", right: "scheduledOutstanding" },
1165
+ { id: "totalOutstanding", op: "sum", left: "scheduledOutstanding", right: "earnedProfit" },
1166
+ { id: "unpaid", op: "less", left: "zeroMoney", right: "totalOutstanding" },
1139
1167
  { id: "elapsed", op: "daysBetween", left: "due", right: "observed" },
1140
1168
  { id: "nonnegativeDays", op: "maximum", left: "elapsed", right: "zeroDays" },
1141
1169
  { id: "daysPastDue", op: "choose", condition: "unpaid", yes: "nonnegativeDays", no: "zeroDays" }