business-as-code 2.1.3 → 2.4.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/.turbo/turbo-build.log +4 -5
- package/CHANGELOG.md +53 -0
- package/README.md +2 -0
- package/dist/dollar.d.ts.map +1 -1
- package/dist/dollar.js +2 -2
- package/dist/dollar.js.map +1 -1
- package/dist/entities/organization.d.ts +4 -0
- package/dist/entities/organization.d.ts.map +1 -1
- package/dist/entities/organization.js +27 -18
- package/dist/entities/organization.js.map +1 -1
- package/dist/entities/planning.d.ts +87 -0
- package/dist/finance/account.d.ts +44 -0
- package/dist/finance/account.d.ts.map +1 -0
- package/dist/finance/account.js +6 -0
- package/dist/finance/account.js.map +1 -0
- package/dist/finance/authority.d.ts +78 -0
- package/dist/finance/authority.d.ts.map +1 -0
- package/dist/finance/authority.js +27 -0
- package/dist/finance/authority.js.map +1 -0
- package/dist/finance/card.d.ts +36 -0
- package/dist/finance/card.d.ts.map +1 -0
- package/dist/finance/card.js +6 -0
- package/dist/finance/card.js.map +1 -0
- package/dist/finance/identity.d.ts +30 -0
- package/dist/finance/identity.d.ts.map +1 -0
- package/dist/finance/identity.js +8 -0
- package/dist/finance/identity.js.map +1 -0
- package/dist/finance/index.d.ts +36 -0
- package/dist/finance/index.d.ts.map +1 -0
- package/dist/finance/index.js +22 -0
- package/dist/finance/index.js.map +1 -0
- package/dist/finance/ledger.d.ts +24 -0
- package/dist/finance/ledger.d.ts.map +1 -0
- package/dist/finance/ledger.js +8 -0
- package/dist/finance/ledger.js.map +1 -0
- package/dist/finance/merchant.d.ts +129 -0
- package/dist/finance/merchant.d.ts.map +1 -0
- package/dist/finance/merchant.js +21 -0
- package/dist/finance/merchant.js.map +1 -0
- package/dist/finance/outcome-contract.d.ts +139 -0
- package/dist/finance/outcome-contract.d.ts.map +1 -0
- package/dist/finance/outcome-contract.js +27 -0
- package/dist/finance/outcome-contract.js.map +1 -0
- package/dist/finance/port.d.ts +121 -0
- package/dist/finance/port.d.ts.map +1 -0
- package/dist/finance/port.js +10 -0
- package/dist/finance/port.js.map +1 -0
- package/dist/finance/pricing.d.ts +154 -0
- package/dist/finance/pricing.d.ts.map +1 -0
- package/dist/finance/pricing.js +79 -0
- package/dist/finance/pricing.js.map +1 -0
- package/dist/finance/proof-predicate.d.ts +92 -0
- package/dist/finance/proof-predicate.d.ts.map +1 -0
- package/dist/finance/proof-predicate.js +80 -0
- package/dist/finance/proof-predicate.js.map +1 -0
- package/dist/finance/refund.d.ts +44 -0
- package/dist/finance/refund.d.ts.map +1 -0
- package/dist/finance/refund.js +41 -0
- package/dist/finance/refund.js.map +1 -0
- package/dist/finance/sla.d.ts +25 -0
- package/dist/finance/sla.d.ts.map +1 -0
- package/dist/finance/sla.js +7 -0
- package/dist/finance/sla.js.map +1 -0
- package/dist/finance/types.d.ts +79 -0
- package/dist/finance/types.d.ts.map +1 -0
- package/dist/finance/types.js +8 -0
- package/dist/{canvas → finance}/types.js.map +1 -1
- package/dist/goals.d.ts +19 -0
- package/dist/goals.d.ts.map +1 -1
- package/dist/goals.js +81 -12
- package/dist/goals.js.map +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/kpis.d.ts +19 -0
- package/dist/kpis.d.ts.map +1 -1
- package/dist/kpis.js +71 -6
- package/dist/kpis.js.map +1 -1
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +29 -24
- package/dist/metrics.js.map +1 -1
- package/dist/okrs.d.ts +34 -0
- package/dist/okrs.d.ts.map +1 -1
- package/dist/okrs.js +135 -13
- package/dist/okrs.js.map +1 -1
- package/dist/organization.d.ts.map +1 -1
- package/dist/organization.js +11 -11
- package/dist/organization.js.map +1 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +13 -12
- package/dist/process.js.map +1 -1
- package/dist/product.d.ts.map +1 -1
- package/dist/product.js +9 -9
- package/dist/product.js.map +1 -1
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +194 -32
- package/dist/queries.js.map +1 -1
- package/dist/roles.d.ts +25 -31
- package/dist/roles.d.ts.map +1 -1
- package/dist/roles.js +37 -10
- package/dist/roles.js.map +1 -1
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +13 -12
- package/dist/workflow.js.map +1 -1
- package/package.json +20 -13
- package/src/dollar.ts +5 -2
- package/src/entities/organization.ts +31 -18
- package/src/finance/account.ts +48 -0
- package/src/finance/authority.ts +42 -0
- package/src/finance/card.ts +38 -0
- package/src/finance/identity.ts +31 -0
- package/src/finance/index.ts +117 -0
- package/src/finance/ledger.ts +26 -0
- package/src/finance/merchant.ts +127 -0
- package/src/finance/outcome-contract.ts +157 -0
- package/src/finance/port.ts +144 -0
- package/src/finance/pricing.ts +197 -0
- package/src/finance/proof-predicate.ts +106 -0
- package/src/finance/refund.ts +52 -0
- package/src/finance/sla.ts +33 -0
- package/src/finance/types.ts +75 -0
- package/src/goals.ts +78 -12
- package/src/index.ts +48 -18
- package/src/kpis.ts +62 -8
- package/src/metrics.ts +92 -79
- package/src/okrs.ts +120 -20
- package/src/organization.ts +12 -15
- package/src/process.ts +11 -12
- package/src/product.ts +8 -9
- package/src/queries.ts +238 -75
- package/src/roles.ts +62 -61
- package/src/workflow.ts +22 -15
- package/test/business.test.ts +282 -0
- package/test/dollar.test.ts +270 -0
- package/test/entities.test.ts +628 -0
- package/test/financials.test.ts +539 -0
- package/test/goals.test.ts +451 -0
- package/{src → test}/index.test.ts +1 -1
- package/test/kpis.test.ts +440 -0
- package/test/metrics.test.ts +744 -0
- package/test/okrs.test.ts +741 -0
- package/test/organization.test.ts +548 -0
- package/test/process.test.ts +503 -0
- package/test/product.test.ts +430 -0
- package/test/queries.test.ts +556 -0
- package/test/roles.test.ts +546 -0
- package/test/service.test.ts +450 -0
- package/test/types.test.ts +1141 -0
- package/test/vision.test.ts +214 -0
- package/test/workflow.test.ts +501 -0
- package/vitest.config.ts +47 -0
- package/LICENSE +0 -21
- package/dist/canvas/activities.d.ts +0 -19
- package/dist/canvas/activities.d.ts.map +0 -1
- package/dist/canvas/activities.js +0 -20
- package/dist/canvas/activities.js.map +0 -1
- package/dist/canvas/channels.d.ts +0 -20
- package/dist/canvas/channels.d.ts.map +0 -1
- package/dist/canvas/channels.js +0 -21
- package/dist/canvas/channels.js.map +0 -1
- package/dist/canvas/relationships.d.ts +0 -20
- package/dist/canvas/relationships.d.ts.map +0 -1
- package/dist/canvas/relationships.js +0 -21
- package/dist/canvas/relationships.js.map +0 -1
- package/dist/canvas/resources.d.ts +0 -20
- package/dist/canvas/resources.d.ts.map +0 -1
- package/dist/canvas/resources.js +0 -30
- package/dist/canvas/resources.js.map +0 -1
- package/dist/canvas/revenue.d.ts +0 -22
- package/dist/canvas/revenue.d.ts.map +0 -1
- package/dist/canvas/revenue.js +0 -30
- package/dist/canvas/revenue.js.map +0 -1
- package/dist/canvas/segments.d.ts +0 -20
- package/dist/canvas/segments.d.ts.map +0 -1
- package/dist/canvas/segments.js +0 -28
- package/dist/canvas/segments.js.map +0 -1
- package/dist/canvas/types.d.ts +0 -232
- package/dist/canvas/types.d.ts.map +0 -1
- package/dist/canvas/types.js +0 -8
- package/dist/canvas/value.d.ts +0 -20
- package/dist/canvas/value.d.ts.map +0 -1
- package/dist/canvas/value.js +0 -21
- package/dist/canvas/value.js.map +0 -1
- package/src/business.js +0 -108
- package/src/canvas/activities.ts +0 -32
- package/src/canvas/canvas.ts +0 -482
- package/src/canvas/channels.ts +0 -34
- package/src/canvas/costs.ts +0 -43
- package/src/canvas/economics.ts +0 -99
- package/src/canvas/index.ts +0 -206
- package/src/canvas/partnerships.ts +0 -34
- package/src/canvas/projections.ts +0 -141
- package/src/canvas/relationships.ts +0 -34
- package/src/canvas/resources.ts +0 -43
- package/src/canvas/revenue.ts +0 -56
- package/src/canvas/segments.ts +0 -42
- package/src/canvas/types.ts +0 -363
- package/src/canvas/value.ts +0 -34
- package/src/dollar.js +0 -106
- package/src/entities/assets.js +0 -322
- package/src/entities/business.js +0 -369
- package/src/entities/communication.js +0 -254
- package/src/entities/customers.js +0 -988
- package/src/entities/financials.js +0 -931
- package/src/entities/goals.js +0 -799
- package/src/entities/index.js +0 -197
- package/src/entities/legal.js +0 -300
- package/src/entities/market.js +0 -300
- package/src/entities/marketing.js +0 -1156
- package/src/entities/offerings.js +0 -726
- package/src/entities/operations.js +0 -786
- package/src/entities/organization.js +0 -806
- package/src/entities/partnerships.js +0 -299
- package/src/entities/planning.js +0 -270
- package/src/entities/projects.js +0 -348
- package/src/entities/risk.js +0 -292
- package/src/entities/sales.js +0 -1247
- package/src/financials.js +0 -296
- package/src/goals.js +0 -214
- package/src/index.js +0 -131
- package/src/index.test.js +0 -274
- package/src/kpis.js +0 -231
- package/src/metrics.js +0 -324
- package/src/okrs.js +0 -268
- package/src/organization.js +0 -172
- package/src/process.js +0 -240
- package/src/product.js +0 -144
- package/src/queries.js +0 -414
- package/src/roles.js +0 -254
- package/src/service.js +0 -139
- package/src/types.js +0 -4
- package/src/vision.js +0 -67
- package/src/workflow.js +0 -246
- package/tests/canvas.test.ts +0 -842
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentIdentity + AgentMerchant — cross-provider identity for the four
|
|
3
|
+
* agentic-commerce gaps Stripe didn't ship at Sessions 2026:
|
|
4
|
+
* - Agent-as-buyer with delegation (B2A2D, B2A2B)
|
|
5
|
+
* - Agent-as-merchant (Stripe makes you wire through Connect manually)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface AgentIdentity {
|
|
9
|
+
$id: string
|
|
10
|
+
$type: 'AgentIdentity'
|
|
11
|
+
/** Worker the identity is for (Person/Agent/Role); ThingRef shape. */
|
|
12
|
+
workerRef: string
|
|
13
|
+
/**
|
|
14
|
+
* When the agent buys on behalf of someone else (B2A2D, B2A2B).
|
|
15
|
+
* Null when buying for self (B2A or A2A).
|
|
16
|
+
*/
|
|
17
|
+
delegatedFor?: string
|
|
18
|
+
/** OAuth / capability scopes the identity carries. */
|
|
19
|
+
scopes: string[]
|
|
20
|
+
/** Per-provider credentials (Stripe Projects keys, Tempo wallet IDs, etc.). */
|
|
21
|
+
providerCreds: Record<string, unknown>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface AgentMerchant {
|
|
25
|
+
$id: string
|
|
26
|
+
$type: 'AgentMerchant'
|
|
27
|
+
workerRef: string
|
|
28
|
+
/** Account that receives payouts. */
|
|
29
|
+
payoutAccountRef: string
|
|
30
|
+
providerData: Record<string, unknown>
|
|
31
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* business-as-code/finance — the outcome-contract economic substrate.
|
|
3
|
+
*
|
|
4
|
+
* Source of truth for the economic primitives of the agentic economy:
|
|
5
|
+
* Money/Cost/Budget value types, Account/Card/Ledger/Identity payment types,
|
|
6
|
+
* Pricing, OutcomeContract, ProofPredicate, SLAPolicy, RefundContract,
|
|
7
|
+
* AuthorityBoundary, and the FinanceProvider/Merchant ports.
|
|
8
|
+
*
|
|
9
|
+
* Finance is foundational here because it is the core of the default OKRs
|
|
10
|
+
* (Revenue / Growth / Profit). `services-as-software` and `digital-tools`
|
|
11
|
+
* consume these primitives directly from here.
|
|
12
|
+
*
|
|
13
|
+
* Importable via the `business-as-code/finance` subpath export.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// Money + Cost + Budget + spend-control
|
|
19
|
+
export type {
|
|
20
|
+
FiatCurrency,
|
|
21
|
+
StablecoinCurrency,
|
|
22
|
+
CryptoCurrency,
|
|
23
|
+
Currency,
|
|
24
|
+
Money,
|
|
25
|
+
Cost,
|
|
26
|
+
Budget,
|
|
27
|
+
BudgetScope,
|
|
28
|
+
SpendControl,
|
|
29
|
+
CostModel,
|
|
30
|
+
} from './types.js'
|
|
31
|
+
|
|
32
|
+
// Account + transfer
|
|
33
|
+
export type { Account, AccountSpec, TransferOpts, TransferResult } from './account.js'
|
|
34
|
+
|
|
35
|
+
// Card (Issuing)
|
|
36
|
+
export type { Card, CardSpec } from './card.js'
|
|
37
|
+
|
|
38
|
+
// Ledger
|
|
39
|
+
export type { LedgerEntry, LedgerLine } from './ledger.js'
|
|
40
|
+
|
|
41
|
+
// Identity (cross-provider)
|
|
42
|
+
export type { AgentIdentity, AgentMerchant } from './identity.js'
|
|
43
|
+
|
|
44
|
+
// ProofPredicate union + factories
|
|
45
|
+
export type { ProofPredicate } from './proof-predicate.js'
|
|
46
|
+
export {
|
|
47
|
+
SchemaMatch,
|
|
48
|
+
EvaluatorPass,
|
|
49
|
+
HumanSign,
|
|
50
|
+
External,
|
|
51
|
+
LoadBearingPass,
|
|
52
|
+
OverallFloor,
|
|
53
|
+
UnmetRequirementsPass,
|
|
54
|
+
AND,
|
|
55
|
+
OR,
|
|
56
|
+
} from './proof-predicate.js'
|
|
57
|
+
|
|
58
|
+
// Outcome contract + proof of result
|
|
59
|
+
export type {
|
|
60
|
+
OutcomeContract,
|
|
61
|
+
OutcomeContractBase,
|
|
62
|
+
OutcomeContractWithExpiresAt,
|
|
63
|
+
OutcomeContractWithTimeoutDays,
|
|
64
|
+
OutcomeContractWithTiers,
|
|
65
|
+
ProofOfResult,
|
|
66
|
+
} from './outcome-contract.js'
|
|
67
|
+
export { resolveOutcomeAmount } from './outcome-contract.js'
|
|
68
|
+
|
|
69
|
+
// SLA policy
|
|
70
|
+
export type { SLAPolicy, SLATarget } from './sla.js'
|
|
71
|
+
|
|
72
|
+
// Refund contract + catalog
|
|
73
|
+
export type { RefundContractRef } from './refund.js'
|
|
74
|
+
export { RefundContracts } from './refund.js'
|
|
75
|
+
|
|
76
|
+
// Authority boundary + catalog
|
|
77
|
+
export type { AuthorityBoundaryRef } from './authority.js'
|
|
78
|
+
export { AuthorityBoundaries } from './authority.js'
|
|
79
|
+
|
|
80
|
+
// Pricing factories — type + value merged on the same name (Pricing.outcome(...), etc.)
|
|
81
|
+
export type {
|
|
82
|
+
OutcomeTier,
|
|
83
|
+
PerInvocationTier,
|
|
84
|
+
MeteredEntry,
|
|
85
|
+
CompositeBase,
|
|
86
|
+
SubscriptionPlan,
|
|
87
|
+
PercentOfBasis,
|
|
88
|
+
} from './pricing.js'
|
|
89
|
+
export { Pricing, money } from './pricing.js'
|
|
90
|
+
export type { Pricing as PricingValue } from './pricing.js'
|
|
91
|
+
|
|
92
|
+
// Provider port + capabilities
|
|
93
|
+
export type {
|
|
94
|
+
FinanceProvider,
|
|
95
|
+
ProviderCapabilities,
|
|
96
|
+
ProviderRail,
|
|
97
|
+
ChargeOpts,
|
|
98
|
+
ChargeResult,
|
|
99
|
+
RefundResult,
|
|
100
|
+
EscrowHandle,
|
|
101
|
+
ReleaseResult,
|
|
102
|
+
SubscribeOpts,
|
|
103
|
+
Subscription,
|
|
104
|
+
MeterEvent,
|
|
105
|
+
} from './port.js'
|
|
106
|
+
|
|
107
|
+
// Merchant / Connect provisioning (product-line + hosted checkout + payout)
|
|
108
|
+
export type {
|
|
109
|
+
MerchantCapable,
|
|
110
|
+
PriceInterval,
|
|
111
|
+
ProvisionProductOpts,
|
|
112
|
+
ProvisionedProduct,
|
|
113
|
+
CheckoutOpts,
|
|
114
|
+
CheckoutSession,
|
|
115
|
+
PayoutOpts,
|
|
116
|
+
PayoutResult,
|
|
117
|
+
} from './merchant.js'
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LedgerEntry — double-entry record. Every entry IS an Action under the SVO substrate.
|
|
3
|
+
*
|
|
4
|
+
* Invariant: per-currency, sum(debits.amount) === sum(credits.amount).
|
|
5
|
+
* The ledger is append-only; reversals are new entries with opposite sign.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Money } from './types.js'
|
|
9
|
+
|
|
10
|
+
export interface LedgerEntry {
|
|
11
|
+
$id: string
|
|
12
|
+
$type: 'LedgerEntry'
|
|
13
|
+
/** Reference to the underlying Action (digital-objects ActionRef shape). */
|
|
14
|
+
actionRef: string
|
|
15
|
+
debits: LedgerLine[]
|
|
16
|
+
credits: LedgerLine[]
|
|
17
|
+
/** Optional human-readable memo. */
|
|
18
|
+
memo?: string
|
|
19
|
+
/** ISO-8601 timestamp. */
|
|
20
|
+
postedAt: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface LedgerLine {
|
|
24
|
+
accountRef: string
|
|
25
|
+
amount: Money
|
|
26
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merchant provisioning — the platform/Connect half of the FinanceProvider
|
|
3
|
+
* port: turn a priced Offer into a sellable product-line under a holdco, and
|
|
4
|
+
* mint a checkout for it.
|
|
5
|
+
*
|
|
6
|
+
* Motivation (added by explore.startups.studio B4, issue #222): the substrate
|
|
7
|
+
* `FinanceProvider` port modeled CHARGING (`charge`/`refund`/`subscribe`) but
|
|
8
|
+
* not the upstream provisioning a hosted-checkout flow needs:
|
|
9
|
+
* 1. provision a Product + Price under a platform account (Stripe Connect:
|
|
10
|
+
* one platform / holdco, many product-lines), keyed to a caller-supplied
|
|
11
|
+
* durable id (NOT a name — names are mutable),
|
|
12
|
+
* 2. open a hosted Checkout session that returns a redirectable URL,
|
|
13
|
+
* 3. report a payout against the platform balance.
|
|
14
|
+
*
|
|
15
|
+
* Stripe ships all three; the gap was only that the port did not EXPRESS them,
|
|
16
|
+
* so a consumer had to reach past the port into raw Stripe. These types close
|
|
17
|
+
* that gap so the consumer wires through the port (Stripe / Tempo / x402 are
|
|
18
|
+
* interchangeable behind it).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { Money } from './types.js'
|
|
22
|
+
import type { Pricing } from './pricing.js'
|
|
23
|
+
|
|
24
|
+
/** How a provisioned Price recurs — mirrors Stripe `price.recurring.interval`. */
|
|
25
|
+
export type PriceInterval = 'day' | 'week' | 'month' | 'quarter' | 'year'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Provision a per-product-line Product + Price under the platform/holdco
|
|
29
|
+
* account. `merchantRef` is the caller's DURABLE key for the product-line
|
|
30
|
+
* (e.g. a Startup Id) — adapters MUST round-trip it as provider metadata so a
|
|
31
|
+
* re-provision is idempotent on it, NOT on the (mutable) display name.
|
|
32
|
+
*/
|
|
33
|
+
export interface ProvisionProductOpts {
|
|
34
|
+
/** Caller's durable product-line key (e.g. Startup Id). The idempotency anchor. */
|
|
35
|
+
merchantRef: string
|
|
36
|
+
/** Display name for the product (mutable; never used as the key). */
|
|
37
|
+
name: string
|
|
38
|
+
/** Optional product description. */
|
|
39
|
+
description?: string
|
|
40
|
+
/** The unit price of the representative tier. */
|
|
41
|
+
price: Money
|
|
42
|
+
/** Recurring interval; omit for a one-time price. */
|
|
43
|
+
interval?: PriceInterval
|
|
44
|
+
/** The full authored Pricing architecture (carried as provider metadata for audit). */
|
|
45
|
+
pricing?: Pricing
|
|
46
|
+
/** Idempotency key for at-most-once provisioning. */
|
|
47
|
+
idempotencyKey?: string
|
|
48
|
+
/** Provider-specific opts; pass-through. */
|
|
49
|
+
providerOpts?: Record<string, unknown>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ProvisionedProduct {
|
|
53
|
+
$id: string
|
|
54
|
+
$type: 'Product'
|
|
55
|
+
/** Echoed durable product-line key. */
|
|
56
|
+
merchantRef: string
|
|
57
|
+
/** Provider product + price ids. */
|
|
58
|
+
providerData: { provider: string; productId: string; priceId: string }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Open a hosted-checkout session for a provisioned Price. */
|
|
62
|
+
export interface CheckoutOpts {
|
|
63
|
+
/** The provider price id (from {@link ProvisionedProduct}). */
|
|
64
|
+
priceId: string
|
|
65
|
+
/** Caller's durable product-line key — round-tripped onto the resulting payment. */
|
|
66
|
+
merchantRef: string
|
|
67
|
+
/** Quantity of the price to purchase (default 1). */
|
|
68
|
+
quantity?: number
|
|
69
|
+
/** Where the provider redirects on success (may carry a `{CHECKOUT_SESSION_ID}` template). */
|
|
70
|
+
successUrl: string
|
|
71
|
+
/** Where the provider redirects on cancel. */
|
|
72
|
+
cancelUrl: string
|
|
73
|
+
/** Mode of the session: one-time payment vs. recurring subscription. */
|
|
74
|
+
mode?: 'payment' | 'subscription'
|
|
75
|
+
/** Arbitrary metadata to attach to the session + resulting payment (e.g. correlation ids). */
|
|
76
|
+
metadata?: Record<string, string>
|
|
77
|
+
/** Idempotency key for at-most-once session creation. */
|
|
78
|
+
idempotencyKey?: string
|
|
79
|
+
/** Provider-specific opts; pass-through. */
|
|
80
|
+
providerOpts?: Record<string, unknown>
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface CheckoutSession {
|
|
84
|
+
$id: string
|
|
85
|
+
$type: 'CheckoutSession'
|
|
86
|
+
/** The redirectable hosted-checkout URL the buyer is sent to. */
|
|
87
|
+
url: string
|
|
88
|
+
/** Caller's durable product-line key. */
|
|
89
|
+
merchantRef: string
|
|
90
|
+
status: 'open' | 'complete' | 'expired'
|
|
91
|
+
providerData: { provider: string; externalId: string }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface PayoutOpts {
|
|
95
|
+
/** Amount to pay out from the platform balance. */
|
|
96
|
+
amount: Money
|
|
97
|
+
/** The connected/destination account ref receiving the payout. */
|
|
98
|
+
destinationRef: string
|
|
99
|
+
/** Idempotency key for at-most-once payout. */
|
|
100
|
+
idempotencyKey?: string
|
|
101
|
+
providerOpts?: Record<string, unknown>
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface PayoutResult {
|
|
105
|
+
$id: string
|
|
106
|
+
$type: 'Payout'
|
|
107
|
+
amount: Money
|
|
108
|
+
destinationRef: string
|
|
109
|
+
status: 'pending' | 'paid' | 'failed'
|
|
110
|
+
/** ISO-8601 timestamp. */
|
|
111
|
+
createdAt: string
|
|
112
|
+
providerData: { provider: string; externalId: string }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The merchant/platform-provisioning capability set. A FinanceProvider MAY
|
|
117
|
+
* implement these (gated by {@link ProviderCapabilities.merchant}); a
|
|
118
|
+
* charge-only adapter omits them.
|
|
119
|
+
*/
|
|
120
|
+
export interface MerchantCapable {
|
|
121
|
+
/** Provision (idempotently, on `merchantRef`) a Product + Price under the platform/holdco. */
|
|
122
|
+
provisionProduct(opts: ProvisionProductOpts): Promise<ProvisionedProduct>
|
|
123
|
+
/** Open a hosted-checkout session for a provisioned price; returns a redirectable URL. */
|
|
124
|
+
createCheckoutSession(opts: CheckoutOpts): Promise<CheckoutSession>
|
|
125
|
+
/** Report a payout against the platform balance to a destination account. */
|
|
126
|
+
payout?(opts: PayoutOpts): Promise<PayoutResult>
|
|
127
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OutcomeContract — definition-of-done + escrow + release condition.
|
|
3
|
+
* Distinct from OutputContract (technical schema; lives in services-as-software).
|
|
4
|
+
*
|
|
5
|
+
* The predicate is evaluated against the runtime state of a Service invocation;
|
|
6
|
+
* when it passes, escrow releases funds to the seller.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { OutcomeTier } from './pricing.js'
|
|
10
|
+
import type { Money } from './types.js'
|
|
11
|
+
import type { ProofPredicate } from './proof-predicate.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Fields shared by all {@link OutcomeContract} variants.
|
|
15
|
+
*
|
|
16
|
+
* Split from the timeout + amount fields so the discriminated union below can
|
|
17
|
+
* express "exactly one of `expiresAt` / `timeoutDays`" AND "exactly one of
|
|
18
|
+
* `amount` / `tiers`" at the type level.
|
|
19
|
+
*/
|
|
20
|
+
export interface OutcomeContractBase {
|
|
21
|
+
$id: string
|
|
22
|
+
$type: 'OutcomeContract'
|
|
23
|
+
/** Worker (Person/Agent/Role) that bought the outcome. */
|
|
24
|
+
buyer: string
|
|
25
|
+
/** Worker (Person/Agent/Role) that sold/delivers the outcome. */
|
|
26
|
+
seller: string
|
|
27
|
+
/** Service this contract is bound to. */
|
|
28
|
+
serviceRef: string
|
|
29
|
+
predicate: ProofPredicate
|
|
30
|
+
/** Account holding escrowed funds until predicate passes. */
|
|
31
|
+
escrowAccountRef?: string
|
|
32
|
+
onTimeout?: 'auto-cancel' | 'auto-refund' | 'escalate'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Variant carrying an absolute ISO-8601 *timestamp* (e.g.
|
|
37
|
+
* `'2026-05-12T00:00:00Z'`). The runtime treats this as the wall-clock
|
|
38
|
+
* deadline. Carries a single {@link Money} `amount`.
|
|
39
|
+
*/
|
|
40
|
+
export interface OutcomeContractWithExpiresAt extends OutcomeContractBase {
|
|
41
|
+
/**
|
|
42
|
+
* Absolute ISO-8601 timestamp — the contract expires (and `onTimeout` fires)
|
|
43
|
+
* exactly at this instant. For relative durations from contract creation,
|
|
44
|
+
* use {@link OutcomeContractWithTimeoutDays.timeoutDays} instead.
|
|
45
|
+
*/
|
|
46
|
+
expiresAt: string
|
|
47
|
+
timeoutDays?: never
|
|
48
|
+
amount: Money
|
|
49
|
+
tiers?: never
|
|
50
|
+
selectedTierId?: never
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Variant carrying a relative-duration deadline measured in whole days from
|
|
55
|
+
* contract creation. The runtime computes
|
|
56
|
+
* `expiresAt = createdAt + timeoutDays * 24h`. Carries a single {@link Money}
|
|
57
|
+
* `amount`.
|
|
58
|
+
*/
|
|
59
|
+
export interface OutcomeContractWithTimeoutDays extends OutcomeContractBase {
|
|
60
|
+
/**
|
|
61
|
+
* Whole days from contract creation until expiry. Mutually exclusive with
|
|
62
|
+
* {@link OutcomeContractWithExpiresAt.expiresAt}.
|
|
63
|
+
*/
|
|
64
|
+
timeoutDays: number
|
|
65
|
+
expiresAt?: never
|
|
66
|
+
amount: Money
|
|
67
|
+
tiers?: never
|
|
68
|
+
selectedTierId?: never
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Variant carrying a multi-tier `OutcomeTier[]` mirror of
|
|
73
|
+
* `Pricing.outcome.tiers`. Used when the Service quotes a tiered price (e.g.
|
|
74
|
+
* S/M/L by feature complexity) and the headline contract figure should be
|
|
75
|
+
* computed lazily from the chosen tier rather than baked at declaration time.
|
|
76
|
+
*
|
|
77
|
+
* At runtime, `Service.invoke` selects a tier based on input characteristics
|
|
78
|
+
* and sets `selectedTierId`; the headline {@link Money} amount is then
|
|
79
|
+
* computed by `tiers.find(t => t.id === selectedTierId)?.amount`.
|
|
80
|
+
*
|
|
81
|
+
* Carries `timeoutDays` (the tiered variant currently couples with relative-
|
|
82
|
+
* duration deadlines; absolute-deadline + tiers can be added later if a
|
|
83
|
+
* catalog Service needs both).
|
|
84
|
+
*/
|
|
85
|
+
export interface OutcomeContractWithTiers extends OutcomeContractBase {
|
|
86
|
+
/**
|
|
87
|
+
* Whole days from contract creation until expiry. Mutually exclusive with
|
|
88
|
+
* {@link OutcomeContractWithExpiresAt.expiresAt}.
|
|
89
|
+
*/
|
|
90
|
+
timeoutDays: number
|
|
91
|
+
expiresAt?: never
|
|
92
|
+
/**
|
|
93
|
+
* Mirror of `Pricing.outcome.tiers` — one entry per quoted complexity tier
|
|
94
|
+
* (e.g. S / M / L). The runtime resolves the headline amount from the
|
|
95
|
+
* selected tier at invocation time.
|
|
96
|
+
*/
|
|
97
|
+
tiers: OutcomeTier[]
|
|
98
|
+
/**
|
|
99
|
+
* Tier id selected by the runtime at invocation time (e.g. `'S'`). Omitted
|
|
100
|
+
* at declaration time — `Service.invoke` sets it based on input
|
|
101
|
+
* characteristics, then a lazy getter computes the headline {@link Money}
|
|
102
|
+
* amount as `tiers.find(t => t.id === selectedTierId)?.amount`.
|
|
103
|
+
*/
|
|
104
|
+
selectedTierId?: string
|
|
105
|
+
/**
|
|
106
|
+
* The runtime computes the headline amount from the selected tier — never
|
|
107
|
+
* declared inline on this variant.
|
|
108
|
+
*/
|
|
109
|
+
amount?: never
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Discriminated union — exactly one of `expiresAt` / `timeoutDays` is required,
|
|
114
|
+
* and exactly one of `amount` / `tiers` is required.
|
|
115
|
+
*
|
|
116
|
+
* Use {@link OutcomeContractWithExpiresAt} for absolute deadlines + a single
|
|
117
|
+
* {@link Money} amount; use {@link OutcomeContractWithTimeoutDays} for
|
|
118
|
+
* relative durations from contract creation + a single {@link Money} amount;
|
|
119
|
+
* use {@link OutcomeContractWithTiers} when the Service quotes a tiered price
|
|
120
|
+
* (S/M/L) and the runtime selects a tier per-invocation.
|
|
121
|
+
*/
|
|
122
|
+
export type OutcomeContract =
|
|
123
|
+
| OutcomeContractWithExpiresAt
|
|
124
|
+
| OutcomeContractWithTimeoutDays
|
|
125
|
+
| OutcomeContractWithTiers
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Resolve the headline {@link Money} amount on an {@link OutcomeContract},
|
|
129
|
+
* lazily computing from `tiers[selectedTierId]` for the
|
|
130
|
+
* {@link OutcomeContractWithTiers} variant.
|
|
131
|
+
*
|
|
132
|
+
* Returns `undefined` for the tiers variant when no tier has been selected
|
|
133
|
+
* yet (e.g. pre-invocation, at declaration / publish time).
|
|
134
|
+
*/
|
|
135
|
+
export function resolveOutcomeAmount(contract: OutcomeContract): Money | undefined {
|
|
136
|
+
if (contract.tiers !== undefined) {
|
|
137
|
+
if (contract.selectedTierId === undefined) return undefined
|
|
138
|
+
const tier = contract.tiers.find((t) => t.id === contract.selectedTierId)
|
|
139
|
+
if (!tier) return undefined
|
|
140
|
+
return { amount: tier.amount, currency: tier.currency ?? 'USD' }
|
|
141
|
+
}
|
|
142
|
+
return contract.amount
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface ProofOfResult {
|
|
146
|
+
$id: string
|
|
147
|
+
$type: 'ProofOfResult'
|
|
148
|
+
contractRef: string
|
|
149
|
+
/** Worker (Person/Agent/Role) that signed the proof. */
|
|
150
|
+
signedBy: string
|
|
151
|
+
/** ISO-8601 timestamp. */
|
|
152
|
+
signedAt: string
|
|
153
|
+
/** Action that produced the verifiable output. */
|
|
154
|
+
outputRef?: string
|
|
155
|
+
/** Cryptographic signature where applicable. */
|
|
156
|
+
signature?: string
|
|
157
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FinanceProvider — port for adapter implementations (Stripe, Tempo, x402,
|
|
3
|
+
* Privy, Lightspark). Every method is optional and gated by ProviderCapabilities;
|
|
4
|
+
* adapters declare which capabilities they support.
|
|
5
|
+
*
|
|
6
|
+
* Adapter implementations are forthcoming and ship outside the substrate —
|
|
7
|
+
* none are bundled here.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Currency, Money, Cost } from './types.js'
|
|
11
|
+
import type { Account, AccountSpec, TransferOpts, TransferResult } from './account.js'
|
|
12
|
+
import type { Card, CardSpec } from './card.js'
|
|
13
|
+
import type { OutcomeContract, ProofOfResult } from './outcome-contract.js'
|
|
14
|
+
import type { StablecoinCurrency } from './types.js'
|
|
15
|
+
import type { MerchantCapable } from './merchant.js'
|
|
16
|
+
|
|
17
|
+
export type ProviderRail =
|
|
18
|
+
| 'mpp'
|
|
19
|
+
| 'spt'
|
|
20
|
+
| 'x402'
|
|
21
|
+
| 'streaming'
|
|
22
|
+
| 'card'
|
|
23
|
+
| 'wire'
|
|
24
|
+
| 'ach'
|
|
25
|
+
| 'lightning'
|
|
26
|
+
| 'on-chain'
|
|
27
|
+
|
|
28
|
+
export interface ProviderCapabilities {
|
|
29
|
+
payments: boolean
|
|
30
|
+
refunds: boolean
|
|
31
|
+
issuing: boolean
|
|
32
|
+
treasury: boolean
|
|
33
|
+
escrow: boolean
|
|
34
|
+
subscriptions: boolean
|
|
35
|
+
metering: boolean
|
|
36
|
+
/** Platform/Connect product-line provisioning + hosted checkout (see MerchantCapable). */
|
|
37
|
+
merchant: boolean
|
|
38
|
+
multiCurrency: boolean
|
|
39
|
+
currencies: Currency[]
|
|
40
|
+
stablecoins: StablecoinCurrency[]
|
|
41
|
+
rails: ProviderRail[]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ChargeOpts {
|
|
45
|
+
/** Counterparty Worker paying the charge (ThingRef shape). */
|
|
46
|
+
buyer: string
|
|
47
|
+
amount: Money
|
|
48
|
+
/** Service or invocation reference for attribution. */
|
|
49
|
+
ref?: string
|
|
50
|
+
/** Idempotency key for at-most-once semantics. */
|
|
51
|
+
idempotencyKey?: string
|
|
52
|
+
/** Provider-specific opts; pass-through. */
|
|
53
|
+
providerOpts?: Record<string, unknown>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ChargeResult {
|
|
57
|
+
$id: string
|
|
58
|
+
$type: 'Charge'
|
|
59
|
+
amount: Money
|
|
60
|
+
status: 'pending' | 'authorized' | 'captured' | 'failed' | 'refunded'
|
|
61
|
+
/** ISO-8601 timestamp. */
|
|
62
|
+
createdAt: string
|
|
63
|
+
providerData: { provider: string; externalId: string }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface RefundResult {
|
|
67
|
+
$id: string
|
|
68
|
+
$type: 'Refund'
|
|
69
|
+
chargeId: string
|
|
70
|
+
amount: Money
|
|
71
|
+
/** ISO-8601 timestamp. */
|
|
72
|
+
createdAt: string
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface EscrowHandle {
|
|
76
|
+
$id: string
|
|
77
|
+
contractRef: string
|
|
78
|
+
state: 'held' | 'released' | 'expired' | 'cancelled'
|
|
79
|
+
providerData: { provider: string; externalId: string }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface ReleaseResult {
|
|
83
|
+
$id: string
|
|
84
|
+
escrowHandle: string
|
|
85
|
+
releasedAt: string
|
|
86
|
+
/** ISO-8601 timestamp. */
|
|
87
|
+
amount: Money
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface SubscribeOpts {
|
|
91
|
+
buyer: string
|
|
92
|
+
planRef: string
|
|
93
|
+
/** Provider-specific opts; pass-through. */
|
|
94
|
+
providerOpts?: Record<string, unknown>
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface Subscription {
|
|
98
|
+
$id: string
|
|
99
|
+
$type: 'Subscription'
|
|
100
|
+
buyer: string
|
|
101
|
+
planRef: string
|
|
102
|
+
state: 'active' | 'paused' | 'cancelled' | 'past-due'
|
|
103
|
+
/** ISO-8601 timestamp. */
|
|
104
|
+
startedAt: string
|
|
105
|
+
providerData: { provider: string; externalId: string }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface MeterEvent {
|
|
109
|
+
/** Subscription or customer this event meters against. */
|
|
110
|
+
subscriptionRef: string
|
|
111
|
+
event: string
|
|
112
|
+
quantity: bigint
|
|
113
|
+
/** ISO-8601 timestamp. */
|
|
114
|
+
occurredAt: string
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface FinanceProvider extends Partial<MerchantCapable> {
|
|
118
|
+
readonly name: string
|
|
119
|
+
readonly capabilities: ProviderCapabilities
|
|
120
|
+
|
|
121
|
+
// Charge / refund
|
|
122
|
+
charge(opts: ChargeOpts): Promise<ChargeResult>
|
|
123
|
+
refund(chargeId: string, amount?: Money): Promise<RefundResult>
|
|
124
|
+
|
|
125
|
+
// Cards (optional)
|
|
126
|
+
issueCard?(spec: CardSpec): Promise<Card>
|
|
127
|
+
lockCard?(cardId: string): Promise<void>
|
|
128
|
+
|
|
129
|
+
// Treasury (optional)
|
|
130
|
+
openAccount?(spec: AccountSpec): Promise<Account>
|
|
131
|
+
balance?(accountId: string): Promise<Money>
|
|
132
|
+
transfer?(opts: TransferOpts): Promise<TransferResult>
|
|
133
|
+
|
|
134
|
+
// Outcome / escrow (optional; built on MPP Sessions / x402 escrow / native)
|
|
135
|
+
escrow?(contract: OutcomeContract): Promise<EscrowHandle>
|
|
136
|
+
release?(escrowHandle: string, proof: ProofOfResult): Promise<ReleaseResult>
|
|
137
|
+
|
|
138
|
+
// Subscriptions / metering (optional)
|
|
139
|
+
subscribe?(opts: SubscribeOpts): Promise<Subscription>
|
|
140
|
+
meter?(event: MeterEvent): Promise<void>
|
|
141
|
+
|
|
142
|
+
// Cost capture — provider-side cost reporting (e.g. LLM provider per-token)
|
|
143
|
+
captureCost?(cost: Omit<Cost, '$id' | '$type'>): Promise<Cost>
|
|
144
|
+
}
|