Skip to content

Commit 6321b31

Browse files
Merge pull request #42 from IntersectMBO/feat/upgrade-modules-10
feat: upgrade sdk modules
2 parents c682347 + eaa4e67 commit 6321b31

File tree

406 files changed

+37232
-4823
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

406 files changed

+37232
-4823
lines changed

.specs/client-module-workflow.md

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
# Evolution SDK Client Module
2+
3+
## Abstract
4+
5+
This document specifies the Evolution SDK client architecture and normative behaviors for composing provider and wallet capabilities in TypeScript applications. It defines client roles, available operations, upgrade semantics, transaction building constraints, and the error model. Examples illustrate key usage patterns; detailed feature matrices are provided in the Appendix.
6+
7+
## Purpose and Scope
8+
9+
This specification describes how clients are constructed and enhanced with providers and wallets, what operations are available for each client role, and how transaction building and submission behave. It does not define provider-specific protocols, CIP-30 details, or internal implementation; those are covered by code and provider-specific documents. Multi-provider behavior is specified at a high level here and in detail in the Provider Failover specification. For Effect-based vs Promise-based usage, see the [Effect-Promise Architecture Guide](./effect-promise-architecture.md).
10+
11+
## Introduction
12+
13+
The Evolution SDK offers a progressive client model: start with a minimal client and add a provider and/or wallet to unlock read, sign, and submit capabilities. The goal is clear separation of concerns and compile-time safety for what a given client can do.
14+
15+
```mermaid
16+
graph TD
17+
A[MinimalClient] -->|Add Provider| B[ProviderOnlyClient]
18+
A -->|Add Signing Wallet| C[SigningWalletClient]
19+
A -->|Add ReadOnly Wallet| D[ReadOnlyWalletClient]
20+
A -->|Add API Wallet| E[ApiWalletClient]
21+
B -->|Add Signing Wallet| F[SigningClient]
22+
B -->|Add ReadOnly Wallet| G[ReadOnlyClient]
23+
C -->|Add Provider| F
24+
D -->|Add Provider| G
25+
E -->|Add Provider| F
26+
27+
classDef minimal fill:#3b82f6,stroke:#1e3a8a,stroke-width:3px,color:#ffffff,font-weight:bold,font-size:14px
28+
classDef provider fill:#8b5cf6,stroke:#4c1d95,stroke-width:3px,color:#ffffff,font-weight:bold,font-size:14px
29+
classDef signingWallet fill:#f59e0b,stroke:#92400e,stroke-width:3px,color:#ffffff,font-weight:bold,font-size:14px
30+
classDef readOnlyWallet fill:#10b981,stroke:#065f46,stroke-width:3px,color:#ffffff,font-weight:bold,font-size:14px
31+
classDef apiWallet fill:#f97316,stroke:#9a3412,stroke-width:3px,color:#ffffff,font-weight:bold,font-size:14px
32+
classDef readOnlyClient fill:#06b6d4,stroke:#0e7490,stroke-width:3px,color:#ffffff,font-weight:bold,font-size:14px
33+
classDef signingClient fill:#ef4444,stroke:#991b1b,stroke-width:3px,color:#ffffff,font-weight:bold,font-size:14px
34+
35+
class A minimal
36+
class B provider
37+
class C signingWallet
38+
class D readOnlyWallet
39+
class E apiWallet
40+
class F signingClient
41+
class G readOnlyClient
42+
```
43+
44+
Summary:
45+
- MinimalClient: no read/sign/submit
46+
- ProviderOnlyClient: read and submit (where applicable), no signing
47+
- SigningWalletClient: sign only
48+
- ReadOnlyWalletClient: address/rewardAddress only
49+
- ApiWalletClient: CIP-30 sign and submit via wallet API
50+
- ReadOnlyClient: provider + read-only wallet; can query wallet data
51+
- SigningClient: provider + signing wallet or API wallet; full capability
52+
53+
Matrices summarizing exact method availability appear in the Appendix.
54+
55+
## Functional Specification (Normative)
56+
57+
Requirements language: The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be interpreted as described in RFC 2119 and RFC 8174 when, and only when, they appear in all capitals.
58+
59+
### 1. Client roles and conformance
60+
61+
An Evolution SDK client instance conforms to exactly one role at a time:
62+
- MinimalClient
63+
- ProviderOnlyClient
64+
- SigningWalletClient
65+
- ReadOnlyWalletClient
66+
- ApiWalletClient
67+
- ReadOnlyClient
68+
- SigningClient
69+
70+
For each role, the following MUST hold:
71+
- MinimalClient MUST NOT expose provider or wallet operations; it MAY be upgraded.
72+
- ProviderOnlyClient MUST expose provider operations and MAY submit transactions if the provider supports submission; it MUST NOT expose signing.
73+
- SigningWalletClient MUST expose signing and message signing; it MUST NOT expose submission or provider queries.
74+
- ReadOnlyWalletClient MUST expose address() and rewardAddress(); it MUST NOT expose signing, provider queries, or submission.
75+
- ApiWalletClient MUST expose signing and MAY expose submission via the wallet API; it MUST NOT expose provider queries unless upgraded with a provider.
76+
- ReadOnlyClient MUST expose provider queries scoped to the configured address and MUST NOT expose signing.
77+
- SigningClient MUST expose provider queries, transaction building, signing, and submission.
78+
79+
### 2. Network and provider operations
80+
81+
- A client configured with a provider (ProviderOnlyClient, ReadOnlyClient, SigningClient) MUST provide `networkId` and provider query methods (e.g., `getProtocolParameters`, `getUtxos`, `awaitTx`, `evaluateTx`) as listed in the Appendix.
82+
- `submitTx` MUST be available on clients with a provider or API wallet capable of submission (ProviderOnlyClient, ReadOnlyClient, SigningClient, ApiWalletClient).
83+
- Provider implementations and their supported operations are out of scope here; see provider-specific docs. A multi-provider MUST follow the strategy defined in the [Provider Failover specification](./provider-failover.md).
84+
85+
### 3. Wallet operations
86+
87+
- A client configured with a wallet MUST provide `address()` and `rewardAddress()` where the wallet type supports them.
88+
- SigningWalletClient and SigningClient MUST provide `signTx(tx)` and `signMessage(address, payload)`.
89+
- ReadOnlyWalletClient and ReadOnlyClient MUST NOT provide signing methods.
90+
- ApiWalletClient MUST provide signTx and SHOULD provide submitTx if the wallet API supports submission.
91+
92+
### 4. Transaction building
93+
94+
- `newTx()` MUST be exposed only on clients that have a provider (ReadOnlyClient, SigningClient).
95+
- Building a transaction MUST require provider protocol parameters.
96+
- `build()`/`complete()` on ReadOnlyClient MUST produce an unsigned `Transaction`.
97+
- `build()`/`complete()` on SigningClient MUST produce a `SignBuilder` (or equivalent) that can be signed and submitted.
98+
- ApiWalletClient MUST be upgraded to SigningClient (by attaching a provider) before it can build transactions.
99+
100+
### 5. Attachment and upgrade semantics
101+
102+
- `createClient()` without arguments MUST return a MinimalClient.
103+
- `attachProvider(provider)` and `attachWallet(wallet)` MUST return new client instances (i.e., the API is immutable) with upgraded roles as per the Introduction diagram.
104+
- `createClient({ network, provider })` MUST produce a ProviderOnlyClient.
105+
- `createClient({ network, wallet })` MUST produce SigningWalletClient, ReadOnlyWalletClient, or ApiWalletClient depending on wallet type.
106+
- `createClient({ network, provider, wallet })` MUST produce ReadOnlyClient or SigningClient depending on wallet type.
107+
108+
### 6. Error model and effect semantics
109+
110+
- Methods that interact with external systems MUST reject/raise with typed errors: ProviderError for provider failures, WalletError for wallet failures, MultiProviderError for strategy/exhaustion failures, and TransactionBuilderError for builder validation issues.
111+
- The Effect API MUST preserve the same error categories as typed causes; callers MAY use retries, timeouts, and fallbacks. The Promise API MUST be semantically equivalent to running the corresponding Effect program to completion.
112+
- Multi-provider failover MUST adhere to the [Provider Failover specification](./provider-failover.md).
113+
114+
### 7. API equivalence (Effect vs Promise)
115+
116+
For every Promise-returning method, an equivalent Effect program MUST exist under the `client.Effect` namespace with identical semantics regarding success values and error categories.
117+
118+
### 8. Examples (Informative)
119+
120+
Simple creation and upgrade:
121+
```typescript
122+
const client = createClient()
123+
const providerClient = client.attachProvider({ type: "blockfrost", apiKey: "your-key" })
124+
const signingClient = providerClient.attachWallet({ type: "seed", mnemonic: "your mnemonic" })
125+
```
126+
127+
Direct creation:
128+
```typescript
129+
const client = createClient({
130+
network: "mainnet",
131+
provider: { type: "blockfrost", apiKey: "your-key" },
132+
wallet: { type: "seed", mnemonic: "your mnemonic" }
133+
})
134+
```
135+
136+
Browser wallet (CIP-30) with upgrade:
137+
```typescript
138+
const apiClient = createClient({ network: "mainnet", wallet: { type: "api", api: window.cardano.nami } })
139+
const fullClient = apiClient.attachProvider({ type: "blockfrost", apiKey: "your-key" })
140+
```
141+
142+
Signing-only wallet (no submit without provider):
143+
```typescript
144+
const signingWallet = createClient({ network: "mainnet", wallet: { type: "seed", mnemonic: "your mnemonic" } })
145+
// await signingWallet.submitTx(...) // not available
146+
```
147+
148+
Effect usage (retries, timeouts):
149+
```typescript
150+
const program = client.Effect.signTx(tx).pipe(Effect.retry({ times: 3 }), Effect.timeout(30000))
151+
const signed = await Effect.runPromise(program)
152+
```
153+
154+
## Appendix (Informative)
155+
156+
### A. Core methods by role
157+
158+
| Method/Capability | MinimalClient | ProviderOnlyClient | SigningWalletClient | ReadOnlyWalletClient | ApiWalletClient | ReadOnlyClient | SigningClient |
159+
|-------------------|---------------|--------------------|---------------------|----------------------|-----------------|----------------|---------------|
160+
| **Network Access** |
161+
| `networkId` ||||||||
162+
| **Provider Operations** |
163+
| `getProtocolParameters()` ||||||||
164+
| `getUtxos(address)` ||||||||
165+
| `getUtxosWithUnit(address, unit)` ||||||||
166+
| `getUtxoByUnit(unit)` ||||||||
167+
| `getUtxosByOutRef(outRefs)` ||||||||
168+
| `getDelegation(rewardAddress)` ||||||||
169+
| `getDatum(datumHash)` ||||||||
170+
| `awaitTx(txHash)` ||||||||
171+
| `evaluateTx(tx)` ||||||||
172+
| `submitTx(tx)` ||||||||
173+
| **Wallet Operations** |
174+
| `address()` ||||||||
175+
| `rewardAddress()` ||||||||
176+
| `getWalletUtxos()` ||||||||
177+
| `getWalletDelegation()` ||||||||
178+
| `signTx(tx)` ||||||||
179+
| `signMessage(address, payload)` ||||||||
180+
| **Transaction Building** |
181+
| `newTx()` ||||||||
182+
| **Client Composition** |
183+
| `attachProvider()` ||||||||
184+
| `attachWallet()` ||||||||
185+
| `attach(provider, wallet)` ||||||||
186+
187+
### B. Transaction builder capabilities
188+
189+
| Builder Method | ReadOnlyClient | SigningClient | Notes |
190+
|----------------|----------------|---------------|--------|
191+
| `build()` | ✅ → `Transaction` | ✅ → `SignBuilder` | ReadOnlyClient returns unsigned transaction; SigningClient returns a builder with signing capabilities |
192+
193+
Note: Transaction building requires protocol parameters from a provider. ApiWalletClient MUST be upgraded before building.
194+
195+
### C. Provider support (categories)
196+
197+
| Category | Description | Supported Operations |
198+
|----------|-------------|---------------------|
199+
| REST API provider | External REST service | All provider operations |
200+
| Node-backed stack | Local/remote node stack (e.g., indexer + node) | All provider operations |
201+
| Cloud API provider | Managed blockchain API | All provider operations |
202+
| Alternative REST provider | Another REST-based service | All provider operations |
203+
| Multi-provider (strategy) | Failover/hedged strategy | All provider operations with redundancy (see [Provider Failover Specification](./provider-failover.md)) |
204+
205+
### D. Wallet support
206+
207+
| Wallet Type | Client Types | Description | Capabilities |
208+
|-------------|-------------|-------------|--------------|
209+
| **Seed Wallet** | SigningWalletClient, SigningClient | HD wallet from mnemonic | Sign only (no submit without provider) |
210+
| **Private Key** | SigningWalletClient, SigningClient | Single key wallet | Sign only (no submit without provider) |
211+
| **Read-Only** | ReadOnlyWalletClient, ReadOnlyClient | Address monitoring | Query only, no signing |
212+
| **API Wallet (CIP-30)** | ApiWalletClient, SigningClient | Browser extension | Sign + submit via extension |
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# CompleteTxBuilder Workflow Diagram
2+
3+
```mermaid
4+
graph TD
5+
A["Start: complete() Function"] --> B["Phase 1: Setup & Validation"]
6+
B --> B1["Fetch Wallet UTxOs"]
7+
B --> B2["Derive Change Address"]
8+
B --> B3["Validate Options"]
9+
10+
B1 --> C["Phase 2: Initial Coin Selection"]
11+
B2 --> C
12+
B3 --> C
13+
14+
C --> C1["Calculate Asset Delta<br/>outputs + fee - collected - minted"]
15+
C1 --> C2["Filter Required Assets<br/>positive amounts only"]
16+
C2 --> C3["Recursive UTxO Selection<br/>largest-first strategy"]
17+
18+
C3 --> D{"Has Plutus Scripts?"}
19+
20+
D -->|No| F["Phase 5: Skip Script Evaluation"]
21+
D -->|Yes| E["Phase 3: Script Evaluation"]
22+
23+
E --> E1["Build Evaluation Transaction<br/>CML.build_for_evaluation()"]
24+
E1 --> E2{"Local UPLC?"}
25+
26+
E2 -->|Yes| E3["WASM UPLC Evaluation<br/>evalTransaction()"]
27+
E2 -->|No| E4["Provider Evaluation<br/>evalTransactionProvider()"]
28+
29+
E3 --> E5["Apply UPLC Results<br/>applyUPLCEval()"]
30+
E4 --> E6["Apply Provider Results<br/>applyUPLCEvalProvider()"]
31+
32+
E5 --> G["Phase 4: Refined Coin Selection"]
33+
E6 --> G
34+
35+
G --> G1["Recalculate Fee with Script Costs"]
36+
G1 --> G2["Check if Additional UTxOs Needed"]
37+
G2 --> G3{"Need More UTxOs?"}
38+
39+
G3 -->|Yes| G4["Select Additional UTxOs"]
40+
G3 -->|No| H["Phase 5: Collateral Management"]
41+
42+
G4 --> G5{"Script Budget Changed?"}
43+
G5 -->|Yes| E1
44+
G5 -->|No| H
45+
46+
H --> H1["Calculate Collateral Amount<br/>150% of estimated fee"]
47+
H1 --> H2["Find Collateral UTxOs<br/>ADA-only, max 3"]
48+
H2 --> H3["Apply Collateral to Transaction"]
49+
50+
H3 --> I["Phase 6: Final Assembly"]
51+
52+
I --> I1["Complete Partial Programs<br/>Build redeemers with indices"]
53+
I1 --> I2["Final CML Transaction Build"]
54+
I2 --> I3["Apply Final ExUnits"]
55+
56+
I3 --> J["Return Built Transaction"]
57+
58+
F --> I
59+
60+
style A fill:#4a90e2,color:#ffffff,stroke:#2171b5,stroke-width:3px
61+
style B fill:#9b59b6,color:#ffffff,stroke:#8e44ad,stroke-width:3px
62+
style C fill:#27ae60,color:#ffffff,stroke:#229954,stroke-width:3px
63+
style D fill:#f39c12,color:#ffffff,stroke:#e67e22,stroke-width:3px
64+
style E fill:#e74c3c,color:#ffffff,stroke:#c0392b,stroke-width:3px
65+
style F fill:#95a5a6,color:#ffffff,stroke:#7f8c8d,stroke-width:3px
66+
style G fill:#1abc9c,color:#ffffff,stroke:#16a085,stroke-width:3px
67+
style H fill:#f1c40f,color:#2c3e50,stroke:#f39c12,stroke-width:3px
68+
style I fill:#34495e,color:#ffffff,stroke:#2c3e50,stroke-width:3px
69+
style J fill:#2ecc71,color:#ffffff,stroke:#27ae60,stroke-width:4px
70+
71+
classDef phaseBox fill:#ecf0f1,stroke:#34495e,stroke-width:3px,color:#2c3e50
72+
classDef decision fill:#fff3cd,stroke:#856404,stroke-width:3px,color:#856404
73+
classDef subprocess fill:#e8f4f8,stroke:#2980b9,stroke-width:2px,color:#2c3e50
74+
classDef success fill:#d4edda,stroke:#155724,stroke-width:3px,color:#155724
75+
76+
class B,C,E,G,H,I phaseBox
77+
class D,E2,G3,G5 decision
78+
class B1,B2,B3,C1,C2,C3,E1,E3,E4,E5,E6,G1,G2,G4,H1,H2,H3,I1,I2,I3 subprocess
79+
class J success
80+
```
81+
82+
## Detailed Flow Explanation
83+
84+
### Phase Transitions and Decision Points
85+
86+
1. **Setup → Initial Selection**: Always proceeds after validation
87+
2. **Initial Selection → Script Check**: Determines if script evaluation needed
88+
3. **Script Evaluation → Refined Selection**: Only for Plutus script transactions
89+
4. **Refined Selection Loop**: Continues until stable UTxO selection achieved
90+
5. **Collateral Management**: Only applies to script transactions
91+
6. **Final Assembly**: Always completes the transaction building
92+
93+
### Critical Decision Points
94+
95+
#### Script Detection (`Has Plutus Scripts?`)
96+
```typescript
97+
// Determines evaluation path
98+
if (hasPlutusScriptExecutions) {
99+
// Proceed to script evaluation
100+
} else {
101+
// Skip to collateral/final assembly
102+
}
103+
```
104+
105+
#### UPLC vs Provider Evaluation (`Local UPLC?`)
106+
```typescript
107+
if (localUPLCEval !== false) {
108+
// Use WASM UPLC evaluation
109+
applyUPLCEval(uplcResults, txBuilder)
110+
} else {
111+
// Use external provider evaluation
112+
applyUPLCEvalProvider(providerResults, txBuilder)
113+
}
114+
```
115+
116+
#### UTxO Selection Stability (`Need More UTxOs?`)
117+
```typescript
118+
// Check if script costs require additional funds
119+
if (newEstimatedFee > currentCapacity) {
120+
// Select more UTxOs and potentially re-evaluate scripts
121+
return selectAdditionalUTxOs()
122+
}
123+
```
124+
125+
#### Script Budget Changes (`Script Budget Changed?`)
126+
```typescript
127+
// If new inputs change script execution context
128+
if (inputSetChanged && hasSignificantBudgetChange) {
129+
// Re-evaluate scripts with new input context
130+
return reEvaluateScripts()
131+
}
132+
```
133+
134+
### Error Paths (Not Shown in Diagram)
135+
136+
Each phase can fail with specific error types:
137+
- **Phase 1**: Wallet access errors, configuration validation errors
138+
- **Phase 2**: Insufficient funds errors, UTxO availability errors
139+
- **Phase 3**: Script evaluation errors, UPLC compilation errors
140+
- **Phase 4**: Fee calculation errors, UTxO selection errors
141+
- **Phase 5**: Collateral selection errors, protocol limit errors
142+
- **Phase 6**: Redeemer building errors, transaction assembly errors
143+
144+
### Performance Considerations
145+
146+
#### Iterative Loops
147+
- **Coin Selection Loop**: May iterate multiple times for complex asset requirements
148+
- **Script Evaluation Loop**: May re-evaluate if input set changes significantly
149+
- **Minimum ADA Loop**: Continues until change outputs meet minimum requirements
150+
151+
#### Expensive Operations
152+
- **Script Evaluation**: Most expensive operation, especially for complex scripts
153+
- **UTxO Sorting**: O(n log n) for large UTxO sets
154+
- **Recursive Selection**: May examine many UTxO combinations
155+
156+
### State Dependencies
157+
158+
```mermaid
159+
graph LR
160+
A[Wallet UTxOs] --> B[Available Inputs]
161+
B --> C[Selected UTxOs]
162+
C --> D[Draft Transaction]
163+
D --> E[Script Evaluation]
164+
E --> F[Final Transaction]
165+
166+
G[Protocol Parameters] --> B
167+
G --> E
168+
G --> F
169+
170+
H[Transaction Outputs] --> C
171+
H --> D
172+
173+
I[Minted Assets] --> C
174+
I --> D
175+
```
176+
177+
This workflow represents one of the most complex transaction building systems in the Cardano ecosystem, with sophisticated handling of script evaluation, UTxO management, and fee calculation.

0 commit comments

Comments
 (0)