@hyperscale0/hsx 1.0.265 → 1.0.293
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/CHANGELOG.md +36 -5
- package/README.md +3 -3
- package/SECURITY.md +10 -21
- package/bases/lending.hsx +0 -1
- package/bases/wallet.hsx +0 -1
- package/dist/src/bases-bundle.js +2 -2
- package/dist/src/bases-bundle.js.map +1 -1
- package/dist/src/compile.d.ts.map +1 -1
- package/dist/src/compile.js +130 -15
- package/dist/src/compile.js.map +1 -1
- package/dist/src/examples-bundle.d.ts.map +1 -1
- package/dist/src/examples-bundle.js +16 -15
- package/dist/src/examples-bundle.js.map +1 -1
- package/dist/src/std-bundle.d.ts.map +1 -1
- package/dist/src/std-bundle.js +10 -8
- package/dist/src/std-bundle.js.map +1 -1
- package/docs/README.md +46 -31
- package/examples/cards.hsx +2 -2
- package/examples/collections.hsx +2 -2
- package/examples/escrow.hsx +2 -2
- package/examples/financing.hsx +2 -2
- package/examples/insurance.hsx +2 -2
- package/examples/lending.hsx +2 -3
- package/examples/library.hsx +9 -3
- package/examples/marketplace.hsx +2 -2
- package/examples/money.hsx +2 -2
- package/examples/rental-deposit.hsx +9 -27
- package/examples/rental-hire.hsx +23 -0
- package/examples/repair-approval.hsx +2 -2
- package/examples/reporting.hsx +2 -2
- package/examples/savings.hsx +2 -2
- package/examples/serviced.hsx +9 -3
- package/examples/wallet.hsx +2 -4
- package/package.json +4 -4
- package/src/bases-bundle.ts +2 -2
- package/src/compile.ts +170 -19
- package/src/examples-bundle.ts +16 -15
- package/src/std-bundle.ts +10 -8
- package/std/booking.hsx +8 -3
- package/std/collections.hsx +1 -1
- package/std/escrow.hsx +16 -29
- package/std/financing.hsx +21 -48
- package/std/marketplace.hsx +2 -7
- package/std/money.hsx +6 -8
- package/std/purchase.hsx +89 -0
- package/std/rental.hsx +68 -0
- package/std/reporting.hsx +1 -11
- package/std/wallet.hsx +2 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-bundle.js","sourceRoot":"","sources":["../../src/std-bundle.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAgC,IAAI,GAAG,CAAiB;IACpF,CAAC,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"std-bundle.js","sourceRoot":"","sources":["../../src/std-bundle.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAgC,IAAI,GAAG,CAAiB;IACpF,CAAC,aAAa,EAAE,m7LAAm7L,CAAC;IACp8L,CAAC,WAAW,EAAE,6wMAA6wM,CAAC;IAC5xM,CAAC,iBAAiB,EAAE,qrNAAqrN,CAAC;IAC1sN,CAAC,YAAY,EAAE,mkOAAmkO,CAAC;IACnlO,CAAC,eAAe,EAAE,kinFAAkinF,CAAC;IACrjnF,CAAC,eAAe,EAAE,41LAA41L,CAAC;IAC/2L,CAAC,aAAa,EAAE,03UAA03U,CAAC;IAC34U,CAAC,iBAAiB,EAAE,ggTAAggT,CAAC;IACrhT,CAAC,WAAW,EAAE,ogYAAogY,CAAC;IACnhY,CAAC,cAAc,EAAE,svJAAsvJ,CAAC;IACxwJ,CAAC,YAAY,EAAE,y1HAAy1H,CAAC;IACz2H,CAAC,eAAe,EAAE,4o1BAA4o1B,CAAC;IAC/p1B,CAAC,aAAa,EAAE,4hKAA4hK,CAAC;IAC7iK,CAAC,YAAY,EAAE,u8HAAu8H,CAAC;CACx9H,CAAC,CAAC"}
|
package/docs/README.md
CHANGED
|
@@ -42,10 +42,10 @@ hsx cost lesson.hsx
|
|
|
42
42
|
`check` exits zero without output on success. `build` writes canonical UDL;
|
|
43
43
|
without `--out` it prints to stdout. `cost` prints instruction counts, described
|
|
44
44
|
below. `format` prints formatted source or writes it with `--out`. `headers --json`
|
|
45
|
-
prints the header manifest.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
prints the header manifest. Exit 1 means invalid source; exit 2 means a command
|
|
46
|
+
or file error. Diagnostics name the source, line, column, code, problem and
|
|
47
|
+
suggested fix. UDL validation keeps its UDL diagnostic codes; binding errors can
|
|
48
|
+
have names such as
|
|
49
49
|
`subject_party_unbound`. Read the message and fix, not just the code.
|
|
50
50
|
|
|
51
51
|
At runtime, create a lesson object first, then call `book_lesson` to create its
|
|
@@ -56,39 +56,44 @@ and party IDs are not metadata supplied by the caller.
|
|
|
56
56
|
|
|
57
57
|
## A rental deposit in one hour
|
|
58
58
|
|
|
59
|
+
For a separate hire charge and refundable security, use
|
|
60
|
+
[rental-hire.hsx](../examples/rental-hire.hsx) and the `rental` header.
|
|
61
|
+
Its shared rules refund both paid parts on cancellation before pickup.
|
|
62
|
+
`complete_hire` requires recorded pickup, and an ended hire still counts toward
|
|
63
|
+
the one-hire limit. The operator records pickup, return and damage.
|
|
64
|
+
|
|
59
65
|
Open [rental-deposit.hsx](../examples/rental-deposit.hsx). It is a complete source
|
|
60
|
-
file for a
|
|
66
|
+
file for a customer renting equipment from the program operator. Copy it to
|
|
61
67
|
`rental.hsx` and run the same check, build and cost commands against that file.
|
|
62
68
|
No header import is needed because it declares its own instrument.
|
|
63
69
|
|
|
64
|
-
The terms are a 1,000 SAR deposit and
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
The terms are a 1,000 SAR deposit and one late charge of 50 SAR plus 15% VAT,
|
|
71
|
+
which is 7.50 SAR. The record's `startsAt` and `dueAt` timestamps reach the
|
|
72
|
+
agreement through `rename`, so `agree_rental` reads them from the object. A
|
|
73
|
+
return before `dueAt` gets the whole deposit back; a return at or after it gets
|
|
74
|
+
942.50 SAR back. The operator receives 50 SAR and `programTax` receives 7.50 SAR.
|
|
75
|
+
The late charge is not a daily charge and is not `financing.late_charge`, which
|
|
68
76
|
requires a financing plan and an overdue installment.
|
|
69
77
|
|
|
70
|
-
| Step | Public action | Actor and required values
|
|
71
|
-
| ---------------------------- | ----------------------- |
|
|
72
|
-
| Create the object | Host object creation | Optional `equipment` metadata
|
|
73
|
-
| Agree terms | `agree_rental` | Bound renter; `dueAt`, for example `2027-01-10T12:00:00+03:00`,
|
|
74
|
-
| Fund before
|
|
75
|
-
| Record an on-time return | `return_equipment` | Operator
|
|
76
|
-
| Or record a late return | `return_equipment_late` | Operator
|
|
77
|
-
| Cancel
|
|
78
|
+
| Step | Public action | Actor and required values | Money effect |
|
|
79
|
+
| ---------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
80
|
+
| Create the object | Host object creation | Optional `equipment`, `serialNumber`, `renterName`, `startsAt` and `dueAt` metadata | None |
|
|
81
|
+
| Agree terms | `agree_rental` | Bound renter; `startsAt` and `dueAt`, for example `2027-01-10T12:00:00+03:00`, both future, `dueAt` later | Creates the agreement's held account |
|
|
82
|
+
| Fund before pickup | `pay_deposit` | Bound renter with 1,000 SAR available, before `startsAt` | Renter pays 1,000 SAR into held |
|
|
83
|
+
| Record an on-time return | `return_equipment` | Operator, before `dueAt`; `returnReference` metadata | Held pays 1,000 SAR to renter |
|
|
84
|
+
| Or record a late return | `return_equipment_late` | Operator, at or after `dueAt`; `returnReference` metadata | Held pays 50 SAR to operator, 7.50 SAR to tax and 942.50 SAR to renter |
|
|
85
|
+
| Cancel before pickup | `cancel_before_pickup` | Bound renter on a funded agreement, before `startsAt` | Held pays 1,000 SAR back to renter |
|
|
86
|
+
| Cancel an unfunded agreement | `cancel_unpaid_rental` | Bound renter, while pending | None |
|
|
78
87
|
|
|
79
88
|
Choose one return action. Both finish the agreement, so the fee and refund cannot
|
|
80
|
-
repeat. The late action calculates the refund from the held balance before
|
|
89
|
+
repeat. The late action calculates the refund from the held balance before any
|
|
81
90
|
move runs. Both paths empty the held account. `returnReference` records the
|
|
82
91
|
operator's return evidence; it does not verify the physical return. Time means
|
|
83
92
|
the executor's current time when the action runs, not a caller-supplied return date.
|
|
84
93
|
A late `due` permits the operator action; it does not schedule that action.
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
parameters. Changing the renter binding is a Build configuration decision, not a
|
|
89
|
-
different party ID on each request. For per-object participants, give a program
|
|
90
|
-
instrument parameters as a header would, such as `instrument purse(holder: party)`,
|
|
91
|
-
and bind `holder: owner` or `holder: actor` in each `attach` block. A
|
|
95
|
+
The renter is a party parameter bound to the rental object's `owner`. Each rental
|
|
96
|
+
can belong to a different customer without a fixed business binding. A
|
|
92
97
|
parameterized program instrument exists only through its attachments. A `fee` on
|
|
93
98
|
a move of an action input, such as `moves input.amount from holder to self.held
|
|
94
99
|
fee { seller: 1% }`, is calculated when that action runs. Reusable custom headers
|
|
@@ -97,8 +102,7 @@ this CLI.
|
|
|
97
102
|
|
|
98
103
|
Inspect `objects` in the compiled UDL for the attachment and public names, then
|
|
99
104
|
its instrument for fields, transitions, actors, requirements and ordered moves.
|
|
100
|
-
|
|
101
|
-
the attachment exposes its own copy. `money.hold` and `escrow.hold` both refund
|
|
105
|
+
`money.hold` and `escrow.hold` both refund
|
|
102
106
|
whole amounts, so neither implements this partial-refund policy by itself.
|
|
103
107
|
|
|
104
108
|
A local compile gives you a contract. Executing it needs a host with authenticated
|
|
@@ -189,7 +193,7 @@ and basis points. Fee and tax calculations round down. Split percentages sum to
|
|
|
189
193
|
schedules use positions 1 through n and put the division remainder in position 1.
|
|
190
194
|
Amortizing financing is the exception: it rounds half up and puts the remainder in
|
|
191
195
|
the last instalment, as a standard amortization table does.
|
|
192
|
-
Tax binds `programTax`. Fees
|
|
196
|
+
Tax binds `programTax`. Fees go to `programOperator`. Fine, recovery and
|
|
193
197
|
residual destinations are party tunables.
|
|
194
198
|
|
|
195
199
|
Attached actions are private unless the attachment exposes them with
|
|
@@ -284,8 +288,9 @@ maxAge 1d` requires a recent completed provider check.
|
|
|
284
288
|
only to reservations. Fees settle with create moves, never reservations. A fee move
|
|
285
289
|
also derives `<action>_<move>_debit`, the payer's whole debit: amount plus fee and
|
|
286
290
|
tax when the buyer pays, the amount alone when the seller pays. Repeated clauses keep
|
|
287
|
-
their declaration order.
|
|
288
|
-
|
|
291
|
+
their declaration order. A clause list after a colon, such as `calculate: [{ ... }]`
|
|
292
|
+
or `invoke: [{ ... }]`, writes [UDL clauses](https://github.com/hyperscale0/hyperscale-udl/blob/main/spec/README.md)
|
|
293
|
+
directly; the std headers use it for calculations, `set` and invocations.
|
|
289
294
|
Use `economics { purpose: earning, sourceParty: merchant }` on a move to
|
|
290
295
|
classify posted money. Other purposes are `principal`, `participant_payout`,
|
|
291
296
|
`internal`, `prepaid_credit`, and `pass_through`. `reversalOf: self.originalTransfer` links a
|
|
@@ -369,7 +374,8 @@ the selection limit, so a count is an upper bound rather than observed usage.
|
|
|
369
374
|
Zero-valued moves can cost fewer actual transfers than their static count.
|
|
370
375
|
|
|
371
376
|
The rental attachment's create declares one owned account, fund declares one
|
|
372
|
-
transfer, on-time return one, and late return
|
|
377
|
+
transfer, on-time return one, and late return three: the charge, its VAT and
|
|
378
|
+
the refund. These are counts, not SAR
|
|
373
379
|
prices. The executor's tariff supplies commercial prices and actual usage.
|
|
374
380
|
|
|
375
381
|
The compiler API is `compile(source)`. On success, `result.verdict` is `valid`
|
|
@@ -395,7 +401,16 @@ customer: `financing.limits` and `financing.installments` (borrower),
|
|
|
395
401
|
(member). Several customers can each start one on the same record. A plan,
|
|
396
402
|
commitment or other reference resolves the sibling that binds the same
|
|
397
403
|
accounts to the parties both share, so each customer's plan finds its own
|
|
398
|
-
|
|
404
|
+
checkout and each investor's commitment finds their own wallet.
|
|
405
|
+
|
|
406
|
+
A financed purchase connects `financing.installments` to `escrow.hold` through
|
|
407
|
+
`purchase.checkout`. Bind the plan's `funds` to checkout, checkout's `funds` to
|
|
408
|
+
the hold, and checkout's `plans` to the plan. Give the hold the funding policy
|
|
409
|
+
`{ controllers: [checkout], reference: "funds", blocking_states: [active] }`.
|
|
410
|
+
If a marketplace reservation contributes a deposit, its `converters` also names
|
|
411
|
+
checkout. Create the hold, then checkout, then the plan. The coordinator collects
|
|
412
|
+
the missing down payment and returns outstanding lender capital before a buyer
|
|
413
|
+
refund. See [library.hsx](../examples/library.hsx) for the complete wiring.
|
|
399
414
|
|
|
400
415
|
`financing.limits` and `financing.portfolio_limit` declare `scope: product`.
|
|
401
416
|
Create and approve the portfolio limit once per Product and the borrower limit
|
package/examples/cards.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Boston catering cards lets staff reserve supplier purchases up to 5,000 SAR each.
|
|
2
2
|
// Supplier cancellation releases the reservation; captured purchases support a full refund or a reviewed dispute.
|
|
3
|
-
program team_expense_cards "
|
|
3
|
+
program team_expense_cards "Boston catering cards"
|
|
4
4
|
use cards
|
|
5
5
|
party supplier: business
|
|
6
6
|
|
package/examples/collections.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Portland cafe equipment finance lends 24,000 SAR over 12 months and refers debt seven days overdue.
|
|
2
2
|
// Its agency earns 10% of each recovery from the lender, with at most four contacts per 30 days.
|
|
3
|
-
program business_collections "
|
|
3
|
+
program business_collections "Portland cafe equipment finance"
|
|
4
4
|
use collections
|
|
5
5
|
use financing
|
|
6
6
|
party agency: business
|
package/examples/escrow.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Seattle used laptops holds a buyer's 2,300 SAR until the laptop arrives and passes inspection.
|
|
2
2
|
// Delivery has seven days; the buyer has 48 hours to accept or dispute before the operator reviews the sale.
|
|
3
|
-
program used_device_sales "
|
|
3
|
+
program used_device_sales "Seattle used laptops"
|
|
4
4
|
use escrow
|
|
5
5
|
party seller: business
|
|
6
6
|
|
package/examples/financing.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Boston language academy finance pays 6,900 SAR tuition to the academy at enrolment.
|
|
2
2
|
// The student repays three monthly instalments of 2,300 SAR with no financing profit or late fee.
|
|
3
|
-
program tuition_instalments "
|
|
3
|
+
program tuition_instalments "Boston language academy finance"
|
|
4
4
|
use financing
|
|
5
5
|
party academy: business
|
|
6
6
|
|
package/examples/insurance.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Portland device cover sells a 1,725 SAR tablet and a 115 SAR annual protection period.
|
|
2
2
|
// The retailer keeps 10% of each premium; cancelled future periods reverse that commission and the insurer's portion.
|
|
3
|
-
program device_insurance "
|
|
3
|
+
program device_insurance "Portland device cover"
|
|
4
4
|
use insurance
|
|
5
5
|
use money
|
|
6
6
|
|
package/examples/lending.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Bristol bakery funding raises 30,000 SAR for ovens from investors who commit at least 1,000 SAR each.
|
|
2
2
|
// An unclosed round refunds its wallets at expiry; funded loans distribute repayments or record investor losses.
|
|
3
|
-
program community_business_lending "
|
|
3
|
+
program community_business_lending "Bristol bakery funding"
|
|
4
4
|
use lending
|
|
5
5
|
use financing
|
|
6
6
|
use wallet
|
|
@@ -42,7 +42,6 @@ object business "Bakery oven funding" {
|
|
|
42
42
|
expose activate as open_wallet
|
|
43
43
|
expose topup as add_funds
|
|
44
44
|
expose withdraw as withdraw_available_funds
|
|
45
|
-
expose close as close_empty_wallet
|
|
46
45
|
}
|
|
47
46
|
attach funding = lending.round {
|
|
48
47
|
borrower: owner, plan: loan, minimum_ticket: 1000 SAR, investor_cap: 25%
|
package/examples/library.hsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Boston used van finance funds a 34,500 SAR van over three monthly instalments.
|
|
2
2
|
// The dealer is paid after delivery and acceptance; a verified return unwinds financing before the buyer gets a refund.
|
|
3
|
-
program cars "
|
|
3
|
+
program cars "Boston used van finance"
|
|
4
4
|
use escrow
|
|
5
5
|
use financing
|
|
6
|
+
use purchase
|
|
6
7
|
party dealer: business
|
|
7
8
|
|
|
8
9
|
// Bind dealer to the vehicle seller. Set price to its gross 34,500 SAR invoice;
|
|
@@ -13,6 +14,7 @@ object car "Financed van purchase" {
|
|
|
13
14
|
columns: [make, model, year, vin, price]
|
|
14
15
|
attach sale = escrow.hold {
|
|
15
16
|
payer: actor, payee: dealer
|
|
17
|
+
funding: { controllers: [checkout], reference: "funds", blocking_states: [active] }
|
|
16
18
|
fee: { seller: 2%, tax: 15% }
|
|
17
19
|
deliver_within: 7d, accept_within: 3d
|
|
18
20
|
expose create as agree_van_purchase
|
|
@@ -42,10 +44,14 @@ object car "Financed van purchase" {
|
|
|
42
44
|
// At 34,500 SAR, 2.5% flat profit is 862.50 SAR for the whole term.
|
|
43
45
|
// Financing fee: 0%, tax: 0% on principal; no separate financing service fee.
|
|
44
46
|
// Supply three future monthly dates and a unique settlementIdentity.
|
|
47
|
+
attach checkout = purchase.checkout {
|
|
48
|
+
plans: plan, funds: sale, borrower: actor, capital: operator
|
|
49
|
+
expose create as prepare_financed_purchase
|
|
50
|
+
}
|
|
45
51
|
attach plan = financing.installments {
|
|
46
52
|
borrower: actor, capital: operator, share: 0%
|
|
47
53
|
months: 3, pricing: flat_total, profit_rate: 2.5%
|
|
48
|
-
funds:
|
|
54
|
+
funds: checkout, limits: limits, portfolio: ceiling
|
|
49
55
|
returned_goods: refund_all, refund_within: 30d, write_off_after: 90d
|
|
50
56
|
expose create as finance
|
|
51
57
|
expose sign as sign_finance_agreement
|
package/examples/marketplace.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Boston design market sells a 2,000 SAR restaurant menu project with delivery in seven days.
|
|
2
2
|
// The company keeps 10% plus 15% VAT on its fee; the designer receives 1,770 SAR after client acceptance.
|
|
3
|
-
program freelance_marketplace "
|
|
3
|
+
program freelance_marketplace "Boston design market"
|
|
4
4
|
use marketplace
|
|
5
5
|
use escrow
|
|
6
6
|
party designer: business
|
package/examples/money.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Boston tutoring studio charges 172.50 SAR for a private Arabic lesson.
|
|
2
2
|
// A paid booking can be refunded before the lesson or if the tutor cannot teach.
|
|
3
|
-
program tutoring_studio "
|
|
3
|
+
program tutoring_studio "Boston tutoring studio"
|
|
4
4
|
use money
|
|
5
5
|
|
|
6
6
|
// The customer is the object's owner. Fee: 0% on top of the lesson price.
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Equipment rental holds a 1,000 SAR deposit for the customer who owns each rental.
|
|
2
2
|
// Return the deposit in full, or deduct a single 50 SAR late charge plus 7.50 SAR VAT.
|
|
3
|
-
program equipment_rental "
|
|
4
|
-
party renter: business
|
|
3
|
+
program equipment_rental "Equipment rental deposits"
|
|
5
4
|
|
|
6
|
-
// Bind renter to the
|
|
5
|
+
// Bind renter to the customer who owns this rental. The deposit has fee 0%
|
|
7
6
|
// and tax 0% because it stays refundable principal. The late service has 15% VAT.
|
|
8
|
-
instrument deposit {
|
|
7
|
+
instrument deposit(renter: party) {
|
|
9
8
|
summary: "Hold security until return, with one disclosed late charge."
|
|
10
9
|
fields {
|
|
11
10
|
renter: account of renter
|
|
@@ -13,20 +12,16 @@ instrument deposit {
|
|
|
13
12
|
amount: money = 1000 SAR
|
|
14
13
|
lateFee: money = 50 SAR
|
|
15
14
|
lateTax: money = rate(self.lateFee, 15%)
|
|
16
|
-
startsAt: date
|
|
17
15
|
dueAt: date
|
|
18
16
|
refund: money?
|
|
19
17
|
}
|
|
20
|
-
lifecycle { states: [pending, funded, returned
|
|
18
|
+
lifecycle { states: [pending, funded, returned], initial: pending }
|
|
21
19
|
action create {
|
|
22
20
|
actor: { party: renter }
|
|
23
21
|
requires self.dueAt > self.now
|
|
24
|
-
requires self.startsAt > self.now
|
|
25
|
-
requires self.dueAt > self.startsAt
|
|
26
22
|
}
|
|
27
23
|
action fund {
|
|
28
24
|
from: pending, to: funded, actor: { party: renter }
|
|
29
|
-
deadline: { at: self.startsAt }
|
|
30
25
|
moves self.amount from self.renter to self.held
|
|
31
26
|
}
|
|
32
27
|
action return_on_time {
|
|
@@ -44,31 +39,18 @@ instrument deposit {
|
|
|
44
39
|
moves self.lateTax from self.held to programTax
|
|
45
40
|
moves self.refund from self.held to self.renter
|
|
46
41
|
}
|
|
47
|
-
|
|
48
|
-
from: funded, to: cancelled, actor: { party: renter }
|
|
49
|
-
deadline: { at: self.startsAt }
|
|
50
|
-
moves self.held.balance from self.held to self.renter
|
|
51
|
-
}
|
|
52
|
-
action cancel { from: pending, to: cancelled, actor: { party: renter } }
|
|
42
|
+
|
|
53
43
|
}
|
|
54
44
|
|
|
55
45
|
object rental "Equipment deposit" {
|
|
56
46
|
fields { equipment: text, serialNumber: text, renterName: text }
|
|
57
|
-
columns: [equipment, serialNumber, renterName,
|
|
47
|
+
columns: [equipment, serialNumber, renterName, dueAt]
|
|
58
48
|
attach security = deposit {
|
|
59
|
-
|
|
49
|
+
renter: owner
|
|
50
|
+
rename { dueAt: dueAt }
|
|
60
51
|
expose create as agree_rental
|
|
61
52
|
expose fund as pay_deposit
|
|
62
53
|
expose return_on_time as return_equipment
|
|
63
54
|
expose return_late as return_equipment_late
|
|
64
|
-
expose refund_before_pickup as cancel_before_pickup
|
|
65
|
-
expose cancel as cancel_unpaid_rental
|
|
66
55
|
}
|
|
67
56
|
}
|
|
68
|
-
|
|
69
|
-
hide deposit.create
|
|
70
|
-
hide deposit.fund
|
|
71
|
-
hide deposit.return_on_time
|
|
72
|
-
hide deposit.return_late
|
|
73
|
-
hide deposit.refund_before_pickup
|
|
74
|
-
hide deposit.cancel
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Equipment rental: refundable security and one hire, earned only after pickup.
|
|
2
|
+
program equipment_hire "Equipment hire and security"
|
|
3
|
+
use rental
|
|
4
|
+
|
|
5
|
+
object rental "Rental deposit" {
|
|
6
|
+
fields { item: text, renter: text, price: money }
|
|
7
|
+
columns: [item, renter, price]
|
|
8
|
+
attach hire = rental.hire_charge {
|
|
9
|
+
renter: owner, security: security
|
|
10
|
+
expose create as agree_hire
|
|
11
|
+
expose fund as pay_hire
|
|
12
|
+
expose release as complete_hire
|
|
13
|
+
}
|
|
14
|
+
attach security = rental.deposit {
|
|
15
|
+
renter: owner, hire: hire
|
|
16
|
+
rename { price: price }
|
|
17
|
+
expose create as agree_rental
|
|
18
|
+
expose fund as pay_deposit
|
|
19
|
+
expose pickup as collect_equipment
|
|
20
|
+
expose return as return_equipment
|
|
21
|
+
expose withhold as withhold_damage
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Portland phone repair quotes 350 SAR plus 52.50 SAR VAT for a screen replacement.
|
|
2
2
|
// The customer approves and funds the repair; acceptance pays the shop, while a failed repair returns all 402.50 SAR.
|
|
3
|
-
program repair_shop "
|
|
3
|
+
program repair_shop "Portland phone repair"
|
|
4
4
|
|
|
5
5
|
// Fee: 0% beyond the repair price. The shop keeps 350 SAR and posts 15% VAT.
|
|
6
6
|
instrument assessment(customer: party) {
|
package/examples/reporting.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Lyon workshop equipment finance lends 46,000 SAR and reports monthly repayments and arrears.
|
|
2
2
|
// Ageing bands at 30, 60 and 90 days distinguish overdue balances from loans written off after 90 days.
|
|
3
|
-
program equipment_loan_reports "
|
|
3
|
+
program equipment_loan_reports "Lyon workshop equipment finance"
|
|
4
4
|
use reporting
|
|
5
5
|
use financing
|
|
6
6
|
|
package/examples/savings.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Seattle shopkeepers circle collects 500 SAR from each of six members every month.
|
|
2
2
|
// Each member receives one 3,000 SAR pot in order; missed contributions remain payable and an unfunded pot waits.
|
|
3
|
-
program neighbourhood_savings "
|
|
3
|
+
program neighbourhood_savings "Seattle shopkeepers circle"
|
|
4
4
|
use savings
|
|
5
5
|
|
|
6
6
|
// Fee: 0%. Tax: 0% because this circle only returns members' principal and
|
package/examples/serviced.hsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Denver delivery van finance funds a 69,000 SAR van with 10% down and 36 monthly instalments.
|
|
2
2
|
// It records reminders, late charges, hardship extensions, early repayment and financed returns.
|
|
3
|
-
program car_financing "
|
|
3
|
+
program car_financing "Denver delivery van finance"
|
|
4
4
|
use escrow
|
|
5
5
|
use financing
|
|
6
|
+
use purchase
|
|
6
7
|
use collections
|
|
7
8
|
party dealer: business
|
|
8
9
|
|
|
@@ -13,6 +14,7 @@ object car "Delivery van finance" {
|
|
|
13
14
|
columns: [make, model, year, vin, price]
|
|
14
15
|
attach sale = escrow.hold {
|
|
15
16
|
payer: actor, payee: dealer
|
|
17
|
+
funding: { controllers: [checkout], reference: "funds", blocking_states: [active] }
|
|
16
18
|
fee: { seller: 1%, tax: 15% }, deliver_within: 14d, accept_within: 3d
|
|
17
19
|
expose create as agree_van_purchase
|
|
18
20
|
expose fund as pay_cash_instead
|
|
@@ -40,13 +42,17 @@ object car "Delivery van finance" {
|
|
|
40
42
|
// Down payment is 6,900 SAR. Capital is 62,100 SAR; total flat profit is
|
|
41
43
|
// 5,278.50 SAR. Financing service fee: 0%, tax: 0% on principal repayments.
|
|
42
44
|
// Supply 36 future monthly dates. Approve limits before collecting and funding.
|
|
45
|
+
attach checkout = purchase.checkout {
|
|
46
|
+
plans: plan, funds: sale, borrower: actor, capital: operator
|
|
47
|
+
expose create as prepare_financed_purchase
|
|
48
|
+
}
|
|
43
49
|
attach plan = financing.installments {
|
|
44
50
|
borrower: actor, capital: operator, share: 0%
|
|
45
51
|
months: 36, pricing: flat_total, profit_rate: 8.5%, down_payment: 10%
|
|
46
52
|
apply: fines_profit_principal, payoff_rebate: 100%, write_off_after: 90d
|
|
47
53
|
refund_within: 30d, payoff_quote_expiry: 1h, returned_goods: refund_all
|
|
48
54
|
max_extension: 60d, max_amendments: 2, amendment_expiry: 7d
|
|
49
|
-
funds:
|
|
55
|
+
funds: checkout, limits: limits, portfolio: ceiling
|
|
50
56
|
expose create as finance
|
|
51
57
|
expose sign as sign_contract
|
|
52
58
|
expose collect_down_payment as pay_down_payment
|
package/examples/wallet.hsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// York pottery studio lets members prepay for visits at 172.50 SAR each.
|
|
2
2
|
// A reserved visit can be charged, cancelled or released at expiry; unused credit can be withdrawn.
|
|
3
|
-
program workshop_credits "
|
|
3
|
+
program workshop_credits "York pottery studio"
|
|
4
4
|
use wallet
|
|
5
5
|
|
|
6
6
|
// Top-up fee: 0%. Loading and withdrawing credit have tax 0% here because
|
|
@@ -18,8 +18,6 @@ object membership "Pottery membership" {
|
|
|
18
18
|
expose withdraw as withdraw_unused_credit
|
|
19
19
|
expose freeze as freeze_balance
|
|
20
20
|
expose unfreeze as restore_balance
|
|
21
|
-
expose close as close_empty_balance
|
|
22
|
-
expose operator_close as close_empty_membership
|
|
23
21
|
}
|
|
24
22
|
// Supply amount: 172.50 SAR and expiresAt: the booked visit time.
|
|
25
23
|
// Each spend has its own inputs; a second visit cannot inherit the first.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperscale0/hsx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.293",
|
|
4
4
|
"description": "The strictly typed HSX language: compile total financial programs into canonical UDL.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hsx",
|
|
@@ -90,8 +90,8 @@
|
|
|
90
90
|
"bases:bundle": "bun scripts/bundle-bases.ts"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
|
-
"@hyperscale0/adl": "1.0.
|
|
94
|
-
"@hyperscale0/udl": "1.0.
|
|
93
|
+
"@hyperscale0/adl": "1.0.293",
|
|
94
|
+
"@hyperscale0/udl": "1.0.293",
|
|
95
95
|
"fast-sha256": "1.3.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"Amir Ayub",
|
|
104
104
|
"Sara AlBakaawi"
|
|
105
105
|
],
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "1162996bf1b0230e8bb55a641976ab9bac500aa5"
|
|
107
107
|
}
|
package/src/bases-bundle.ts
CHANGED
|
@@ -6,10 +6,10 @@ export const bases: HsxBase[] = [
|
|
|
6
6
|
{"id":"escrow","title":"Hold payment until delivery","summary":"Hold a buyer’s payment until delivery is accepted.","headers":["escrow"],"source":"// Hold a buyer’s payment until delivery is accepted.\nprogram escrow_base \"Hold payment until delivery\"\nuse escrow\nparty seller: business\n\nobject order \"Order\" {\n fields { price: money }\n attach payment = escrow.hold {\n payer: owner, payee: seller\n expose create as create\n expose fund as fund\n expose deliver as deliver\n expose accept as accept\n expose dispute as dispute\n expose verify_return as verify_return\n expose refund as refund\n expose refund_undelivered as refund_undelivered\n expose settle_release as settle_release\n expose settle_return as settle_return\n expose settle_refund as settle_refund\n expose cancel as cancel\n }\n}\n"},
|
|
7
7
|
{"id":"financing","title":"Split a purchase into instalments","summary":"Fund a purchase and collect its scheduled repayments.","headers":["financing"],"source":"// Fund a purchase and collect its scheduled repayments.\nprogram financing_base \"Split a purchase into instalments\"\nuse financing\nparty seller: business\n\nobject purchase \"Purchase\" {\n fields { price: money }\n attach allowance = financing.limits {\n borrower: owner, per_borrower: runtime\n expose create as request_limit\n expose approve as approve_limit\n }\n attach budget = financing.portfolio_limit {\n limit: runtime\n expose create as create_budget\n expose approve as approve_budget\n }\n // Architect sets the placeholder profit rate during tailoring.\n attach plan = financing.installments {\n borrower: owner, capital: operator\n months: 2, pricing: flat_total, profit_rate: 0%\n disburse_to: seller, seller: seller, limits: allowance, portfolio: budget\n expose create as quote\n expose sign as sign\n expose disburse as fund\n expose cancel as cancel_quote\n expose void as cancel_plan\n expose payoff as repay_early\n expose complete as complete\n }\n}\n\nexpose purchase.plan.payment.create as record_payment\nexpose purchase.plan.payment.pay as pay_instalment\nexpose purchase.plan.payment.refund as refund_payment\nexpose purchase.plan.payoff_quote.create as quote_payoff\n"},
|
|
8
8
|
{"id":"insurance","title":"Protect a purchase","summary":"Collect cover premiums and reserve approved claims for payment.","headers":["insurance"],"source":"// Collect cover premiums and reserve approved claims for payment.\nprogram insurance_base \"Protect a purchase\"\nuse insurance\n\nobject purchase \"Purchase\" {\n attach cover = insurance.cover {\n holder: owner, adapter: \"conformance_boundary\"\n expose create as create_cover\n expose activate as activate_cover\n expose cancel as cancel_cover\n }\n attach claim = insurance.claim {\n cover: cover, inspector: operator\n expose create as create_claim\n expose approve as approve_claim\n expose deny as deny_claim\n expose pay as pay_claim\n }\n}\n\nexpose purchase.cover.slice.create as create_period\nexpose purchase.cover.slice.collect as collect_premium\n"},
|
|
9
|
-
{"id":"lending","title":"Pool funds for lending","summary":"Pool member commitments to fund a loan and distribute repayments or losses.","headers":["lending","financing","wallet"],"source":"// Pool member commitments to fund a loan and distribute repayments or losses.\nprogram lending_base \"Pool funds for lending\"\nuse lending\nuse financing\nuse wallet\n\nobject plan \"Plan\" {\n fields { price: money }\n attach allowance = financing.limits {\n borrower: owner, per_borrower: runtime\n expose create as request_limit\n expose approve as approve_limit\n }\n attach budget = financing.portfolio_limit {\n limit: runtime\n expose create as create_budget\n expose approve as approve_budget\n }\n // Architect sets the placeholder profit rate during tailoring.\n attach plan = financing.installments {\n borrower: owner, capital: operator\n months: 2, pricing: flat_total, profit_rate: 0%\n disburse_to: borrower, limits: allowance, portfolio: budget\n expose create as quote\n expose sign as sign\n expose disburse as fund\n expose cancel as cancel_quote\n expose void as cancel_plan\n expose payoff as repay_early\n expose complete as complete\n }\n attach balance = wallet.balance {\n holder: actor\n expose create as create_balance\n expose activate as activate_balance\n expose topup as add_funds\n expose withdraw as withdraw_funds\n
|
|
9
|
+
{"id":"lending","title":"Pool funds for lending","summary":"Pool member commitments to fund a loan and distribute repayments or losses.","headers":["lending","financing","wallet"],"source":"// Pool member commitments to fund a loan and distribute repayments or losses.\nprogram lending_base \"Pool funds for lending\"\nuse lending\nuse financing\nuse wallet\n\nobject plan \"Plan\" {\n fields { price: money }\n attach allowance = financing.limits {\n borrower: owner, per_borrower: runtime\n expose create as request_limit\n expose approve as approve_limit\n }\n attach budget = financing.portfolio_limit {\n limit: runtime\n expose create as create_budget\n expose approve as approve_budget\n }\n // Architect sets the placeholder profit rate during tailoring.\n attach plan = financing.installments {\n borrower: owner, capital: operator\n months: 2, pricing: flat_total, profit_rate: 0%\n disburse_to: borrower, limits: allowance, portfolio: budget\n expose create as quote\n expose sign as sign\n expose disburse as fund\n expose cancel as cancel_quote\n expose void as cancel_plan\n expose payoff as repay_early\n expose complete as complete\n }\n attach balance = wallet.balance {\n holder: actor\n expose create as create_balance\n expose activate as activate_balance\n expose topup as add_funds\n expose withdraw as withdraw_funds\n }\n attach round = lending.round {\n borrower: owner, plan: plan\n expose create as open_round\n expose close as close_round\n }\n attach commitment = lending.commitment {\n round: round, wallet: balance, investor: actor\n expose create as commit\n expose withdraw as withdraw_commitment\n }\n attach returns = lending.distribution {\n round: round, receipt: plan.settlement\n expose create as record_settlement\n expose prepare_cash as prepare_returns\n expose distribute_cash as distribute_returns\n }\n attach losses = lending.distribution {\n round: round, receipt: plan.settlement, mode: loss\n expose create as record_loss\n expose prepare_loss as prepare_losses\n expose distribute_loss as distribute_losses\n }\n}\n\nexpose plan.plan.payment.create as record_payment\nexpose plan.plan.payment.pay as pay_instalment\nexpose plan.plan.payment.refund as refund_payment\nexpose plan.plan.payoff_quote.create as quote_payoff\n\nexpose plan.returns.share.create as create_return_share\nexpose plan.losses.share.create as create_loss_share\nexpose plan.plan.write_off_request.create as request_write_off\nexpose plan.plan.write_off_request.apply as apply_write_off\nexpose plan.plan.write_off_request.cancel as cancel_write_off\n"},
|
|
10
10
|
{"id":"marketplace","title":"Connect buyers and sellers","summary":"Turn a seller’s offer into an order with payment held until acceptance.","headers":["marketplace","escrow"],"source":"// Turn a seller’s offer into an order with payment held until acceptance.\nprogram marketplace_base \"Connect buyers and sellers\"\nuse marketplace\nuse escrow\nparty seller: business\n\nobject order \"Order\" {\n fields { price: money }\n attach offer = marketplace.listing {\n seller: seller\n expose create as create_offer\n expose publish as publish_offer\n expose withdraw as withdraw_offer\n expose sell as sell_offer\n }\n attach order = marketplace.order {\n listing: offer, buyer: owner, fulfiller: seller\n expose create as create_order\n expose commit as commit_order\n expose fulfill as fulfill_order\n expose cancel as cancel_order\n }\n attach payment = escrow.hold {\n payer: owner, payee: seller\n expose create as create\n expose fund as fund\n expose deliver as deliver\n expose accept as accept\n expose dispute as dispute\n expose verify_return as verify_return\n expose refund as refund\n expose refund_undelivered as refund_undelivered\n expose settle_release as settle_release\n expose settle_return as settle_return\n expose settle_refund as settle_refund\n expose cancel as cancel\n }\n}\n"},
|
|
11
11
|
{"id":"money","title":"Collect a payment","summary":"Collect a payment from a customer.","headers":["money"],"source":"// Collect a payment from a customer.\nprogram money_base \"Collect a payment\"\nuse money\n\nobject purchase \"Purchase\" {\n attach payment = money.transfer {\n payer: owner, payee: operator\n expose create as create\n expose pay as pay\n expose cancel as cancel\n }\n}\n"},
|
|
12
12
|
{"id":"reporting","title":"Track repayments","summary":"Report outstanding balances and overdue repayments on financed purchases.","headers":["reporting","financing"],"source":"// Report outstanding balances and overdue repayments on financed purchases.\nprogram reporting_base \"Track repayments\"\nuse reporting\nuse financing\n\nobject purchase \"Purchase\" {\n fields { price: money }\n attach allowance = financing.limits {\n borrower: owner, per_borrower: runtime\n expose create as request_limit\n expose approve as approve_limit\n }\n attach budget = financing.portfolio_limit {\n limit: runtime\n expose create as create_budget\n expose approve as approve_budget\n }\n // Architect sets the placeholder profit rate during tailoring.\n attach plan = financing.installments {\n borrower: owner, capital: operator\n months: 2, pricing: flat_total, profit_rate: 0%\n disburse_to: borrower, limits: allowance, portfolio: budget\n expose create as quote\n expose sign as sign\n expose disburse as fund\n expose cancel as cancel_quote\n expose void as cancel_plan\n expose payoff as repay_early\n expose complete as complete\n }\n attach reports = reporting.portfolio {\n on: plan\n expose create as create_reports\n }\n}\n\nexpose purchase.plan.payment.create as record_payment\nexpose purchase.plan.payment.pay as pay_instalment\nexpose purchase.plan.payment.refund as refund_payment\nexpose purchase.plan.payoff_quote.create as quote_payoff\n"},
|
|
13
13
|
{"id":"savings","title":"Save as a group","summary":"Collect contributions into a shared pot and pay each member in turn.","headers":["savings"],"source":"// Collect contributions into a shared pot and pay each member in turn.\nprogram savings_base \"Save as a group\"\nuse savings\n\nobject pot \"Pot\" {\n attach circle = savings.circle {\n contribution: runtime, members: 2, starts: runtime\n expose create as create_circle\n expose disband as disband_circle\n expose close as close_circle\n }\n attach membership = savings.membership {\n circle: circle, member: actor\n expose create as join\n expose activate as activate_membership\n expose withdraw as withdraw\n }\n}\n\nexpose pot.membership.contribution.create as schedule_contribution\n"},
|
|
14
|
-
{"id":"wallet","title":"Offer prepaid credit","summary":"Let a customer add funds and reserve each spend before payment.","headers":["wallet"],"source":"// Let a customer add funds and reserve each spend before payment.\nprogram wallet_base \"Offer prepaid credit\"\nuse wallet\n\nobject balance \"Balance\" {\n attach balance = wallet.balance {\n holder: owner\n expose create as create_balance\n expose activate as activate_balance\n expose topup as add_funds\n expose withdraw as withdraw_funds\n expose freeze as freeze_balance\n expose unfreeze as unfreeze_balance\n
|
|
14
|
+
{"id":"wallet","title":"Offer prepaid credit","summary":"Let a customer add funds and reserve each spend before payment.","headers":["wallet"],"source":"// Let a customer add funds and reserve each spend before payment.\nprogram wallet_base \"Offer prepaid credit\"\nuse wallet\n\nobject balance \"Balance\" {\n attach balance = wallet.balance {\n holder: owner\n expose create as create_balance\n expose activate as activate_balance\n expose topup as add_funds\n expose withdraw as withdraw_funds\n expose freeze as freeze_balance\n expose unfreeze as unfreeze_balance\n }\n attach spend = wallet.spend {\n wallet: balance, payee: operator, holder: owner\n expose create as create\n expose reserve as reserve\n expose pay as pay\n expose cancel as cancel\n }\n}\n"},
|
|
15
15
|
];
|