@invisible-labs/sdk 0.6.0-devnet.2 → 0.6.0-devnet.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +186 -70
- package/dist/.invisible-sdk-build-target.json +7 -0
- package/dist/{chunk-TQNNTV5F.js → chunk-4X5OCCQW.js} +3 -3
- package/dist/{chunk-TQNNTV5F.js.map → chunk-4X5OCCQW.js.map} +1 -1
- package/dist/{chunk-7DSVN3MV.js → chunk-5NNEO7IK.js} +41 -36
- package/dist/chunk-5NNEO7IK.js.map +1 -0
- package/dist/chunk-BRDLLGCZ.js +59 -0
- package/dist/chunk-BRDLLGCZ.js.map +1 -0
- package/dist/{chunk-NCY4FCYU.js → chunk-DIA6U2CV.js} +19 -3
- package/dist/chunk-DIA6U2CV.js.map +1 -0
- package/dist/{chunk-LBC7ALYO.js → chunk-E4DCEDAG.js} +177 -12
- package/dist/chunk-E4DCEDAG.js.map +1 -0
- package/dist/{chunk-OHIM2YWU.js → chunk-GHBQF3A7.js} +2 -2
- package/dist/chunk-GHBQF3A7.js.map +1 -0
- package/dist/{chunk-SZAYO2L5.js → chunk-NHEHCUS5.js} +3 -3
- package/dist/{chunk-SZAYO2L5.js.map → chunk-NHEHCUS5.js.map} +1 -1
- package/dist/{chunk-XUWBGET5.js → chunk-UADJCUPK.js} +125 -18
- package/dist/chunk-UADJCUPK.js.map +1 -0
- package/dist/{chunk-JRMKCE3S.js → chunk-V5HXJRBW.js} +3 -3
- package/dist/{chunk-JRMKCE3S.js.map → chunk-V5HXJRBW.js.map} +1 -1
- package/dist/{coordinator-7Y45MCCZ.js → coordinator-ZNLGAYXD.js} +3 -3
- package/dist/{coordinator-7Y45MCCZ.js.map → coordinator-ZNLGAYXD.js.map} +1 -1
- package/dist/events.js +3 -3
- package/dist/index.d.ts +62 -300
- package/dist/index.js +98 -43
- package/dist/index.js.map +1 -1
- package/dist/lp.d.ts +51 -10
- package/dist/lp.js +313 -86
- package/dist/lp.js.map +1 -1
- package/dist/presets.d.ts +5 -42
- package/dist/presets.js +11 -62
- package/dist/presets.js.map +1 -1
- package/dist/stats.js +1 -1
- package/dist/storage.js +1 -1
- package/dist/{createSession-D3ym-Ira.d.ts → types.generated-DJBTjLpP.d.ts} +37 -53
- package/dist/user.d.ts +94 -112
- package/dist/user.js +649 -248
- package/dist/user.js.map +1 -1
- package/package.json +2 -28
- package/dist/chunk-7DSVN3MV.js.map +0 -1
- package/dist/chunk-LBC7ALYO.js.map +0 -1
- package/dist/chunk-NCY4FCYU.js.map +0 -1
- package/dist/chunk-OHIM2YWU.js.map +0 -1
- package/dist/chunk-XUWBGET5.js.map +0 -1
- package/dist/types.generated-CHGSbmLp.d.ts +0 -67
package/README.md
CHANGED
|
@@ -7,8 +7,11 @@ TypeScript SDK for building private SOL transfer integrations with Invisible.
|
|
|
7
7
|
[API reference](https://docs.invisible.exchange/docs/sdk/reference/) ·
|
|
8
8
|
[Trust model](https://docs.invisible.exchange/docs/security/)
|
|
9
9
|
|
|
10
|
-
> Devnet beta. This release targets Solana devnet. APIs may change before a
|
|
11
|
-
|
|
10
|
+
> Devnet beta. This release targets Solana devnet. APIs may change before a stable release.
|
|
11
|
+
|
|
12
|
+
This package is the programmatic entrypoint for user and LP interaction with an attested Invisible
|
|
13
|
+
coordinator. The normal-user surface uses one functional sequence over a caller-owned session:
|
|
14
|
+
`createSession`, `contractRequest`, `sync`, `requestRefund`, then `closeSession`.
|
|
12
15
|
|
|
13
16
|
## Install
|
|
14
17
|
|
|
@@ -16,86 +19,162 @@ TypeScript SDK for building private SOL transfer integrations with Invisible.
|
|
|
16
19
|
npm install @invisible-labs/sdk@devnet
|
|
17
20
|
```
|
|
18
21
|
|
|
19
|
-
##
|
|
22
|
+
## Session boundary
|
|
23
|
+
|
|
24
|
+
The public artifact exposes a production-only root facade:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { closeSession, createSession } from "@invisible-labs/sdk";
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
const session = await createSession({
|
|
30
|
+
coordinatorUrl: "wss://tee-azure.invisible.exchange/ws-noise",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Use the session with @invisible-labs/sdk/user or /lp, then:
|
|
34
|
+
closeSession(session);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The public build embeds the approved production attestation tuple. It accepts a
|
|
38
|
+
non-loopback `wss://` URL, but it does not accept `requiredMode`, a coordinator
|
|
39
|
+
pool, release-pin overrides, or local-attestation controls. The private
|
|
40
|
+
workspace build keeps the low-level pool constructor and exposes
|
|
41
|
+
`createDevSession` for explicit local and test flows; that facade is not in the
|
|
42
|
+
public artifact.
|
|
43
|
+
|
|
44
|
+
`sdk.attestation.productionPolicy()` exposes the embedded tuple as read-only
|
|
45
|
+
metadata. It is not a caller-controlled trust input.
|
|
25
46
|
|
|
26
47
|
## Entrypoints
|
|
27
48
|
|
|
28
|
-
| Import |
|
|
29
|
-
| ----------------------------- |
|
|
30
|
-
| `@invisible-labs/sdk` |
|
|
31
|
-
| `@invisible-labs/sdk/user` |
|
|
32
|
-
| `@invisible-labs/sdk/
|
|
33
|
-
| `@invisible-labs/sdk/
|
|
49
|
+
| Import | Covers |
|
|
50
|
+
| ----------------------------- | ------------------------------------------------------ |
|
|
51
|
+
| `@invisible-labs/sdk` | `createSession`, attestation, and coordinator controls |
|
|
52
|
+
| `@invisible-labs/sdk/user` | normal-user commands: private transfer, sync, refund |
|
|
53
|
+
| `@invisible-labs/sdk/lp` | liquidity-provider lifecycle |
|
|
54
|
+
| `@invisible-labs/sdk/stats` | actor-safe read projections |
|
|
55
|
+
| `@invisible-labs/sdk/events` | sync subscriptions |
|
|
56
|
+
| `@invisible-labs/sdk/storage` | storage adapters |
|
|
57
|
+
| `@invisible-labs/sdk/presets` | optional coordinator endpoint presets |
|
|
58
|
+
|
|
59
|
+
Each actor entrypoint is independently importable; pulling one in must not drag the others into a
|
|
60
|
+
consumer bundle. See [ARCHITECTURE.md](./ARCHITECTURE.md) for the layered module map.
|
|
34
61
|
|
|
35
62
|
## Private transfer
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
create a user session:
|
|
64
|
+
The canonical normal-user flow uses one attested session and the functional SDK commands:
|
|
39
65
|
|
|
40
66
|
```ts
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
67
|
+
import { closeSession, createSession } from "@invisible-labs/sdk";
|
|
68
|
+
import {
|
|
69
|
+
contractRequest,
|
|
70
|
+
recoveryCodeFromHex,
|
|
71
|
+
requestRefund,
|
|
72
|
+
sync,
|
|
73
|
+
} from "@invisible-labs/sdk/user";
|
|
74
|
+
|
|
75
|
+
const coordinatorUrl = "wss://tee-azure.invisible.exchange/ws-noise";
|
|
76
|
+
const payoutPolicy = {
|
|
77
|
+
destinations: [{ address: receiverPublicKey, sharePercent: 100 }],
|
|
78
|
+
totalDeadlineMs: 0,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const session = await createSession({ coordinatorUrl });
|
|
48
82
|
try {
|
|
49
|
-
const
|
|
83
|
+
const contract = await contractRequest(session, {
|
|
50
84
|
amountLamports: 3_000_000_000,
|
|
51
|
-
|
|
52
|
-
mode: "instant",
|
|
53
|
-
destination_address: destinationAddress,
|
|
54
|
-
},
|
|
55
|
-
onSyncSecretReady({ secretHex }) {
|
|
56
|
-
saveSyncSecret(secretHex);
|
|
57
|
-
},
|
|
58
|
-
onRecoveryCodeReady({ codeHex }) {
|
|
59
|
-
saveRecoveryCode(codeHex);
|
|
60
|
-
},
|
|
61
|
-
onDepositAddressReady(deposit) {
|
|
62
|
-
showDepositInstructions(deposit);
|
|
63
|
-
},
|
|
85
|
+
payoutPolicy,
|
|
64
86
|
});
|
|
65
|
-
|
|
66
|
-
console.log(
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
const status = await sync(session, contract.swapId, contract.syncSecret);
|
|
88
|
+
console.log(status.state, status.coordinatorTimestampMs);
|
|
89
|
+
|
|
90
|
+
if (status.actor_sync?.snapshot.refundability === "available_now") {
|
|
91
|
+
const receipt = await requestRefund(session, {
|
|
92
|
+
swapId: contract.swapId,
|
|
93
|
+
syncSecret: contract.syncSecret,
|
|
94
|
+
recoveryCode: recoveryCodeFromHex(contract.recoveryCodeHex!),
|
|
95
|
+
});
|
|
96
|
+
console.log(receipt.requestId, receipt.amountLamports);
|
|
97
|
+
}
|
|
69
98
|
} finally {
|
|
70
|
-
|
|
99
|
+
closeSession(session);
|
|
71
100
|
}
|
|
72
101
|
```
|
|
73
102
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
103
|
+
`contractRequest` resolves after durable delegation and before the deposit is observed. Its result
|
|
104
|
+
contains `swapId`, `depositAddress`, `depositExpiresAtMs`, `syncSecret`, and the generated Recovery
|
|
105
|
+
Code. Persist the sync secret and Recovery Code before asking the user to deposit. Send exactly
|
|
106
|
+
`amountLamports` to the deposit address. The `sync` response contains actor-scoped lifecycle truth
|
|
107
|
+
and the coordinator response timestamp; it does not expose an internal payout due timestamp. A
|
|
108
|
+
refund receipt also carries the coordinator-authoritative accepted amount; use that value for
|
|
109
|
+
pending refund accounting and use `sync` for final landing, cancellation, and fee-loss outcomes.
|
|
77
110
|
|
|
78
|
-
|
|
111
|
+
For crash recovery before delegation, persist `policySnapshot` from the contract result and call
|
|
112
|
+
`resumePreDelegation` with it, the `resumeSecret`, and the Recovery Code commitment. When resuming
|
|
113
|
+
DKG, `onDelegateShareReady` is invoked before `DkgRound2` so the generated Alice share can be
|
|
114
|
+
persisted. Resume fails closed if the coordinator acknowledges a different spending policy.
|
|
115
|
+
|
|
116
|
+
## Private-transfer amount limits
|
|
117
|
+
|
|
118
|
+
Use the public user-entry constants for inclusive preflight validation. Values are expressed in
|
|
119
|
+
lamports, matching the `amountLamports` request field. The current V0 bounds are `1.5 SOL`
|
|
120
|
+
(`1_500_000_000` lamports) minimum and `100 SOL` (`100_000_000_000` lamports) maximum.
|
|
121
|
+
The SDK rejects non-safe integers and values outside these bounds before sending a coordinator
|
|
122
|
+
request.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { MAX_ENTRY_AMOUNT_LAMPORTS, MIN_ENTRY_AMOUNT_LAMPORTS } from "@invisible-labs/sdk/user";
|
|
126
|
+
|
|
127
|
+
const isValidEntryAmount = (amountLamports: number) =>
|
|
128
|
+
Number.isSafeInteger(amountLamports) &&
|
|
129
|
+
amountLamports >= MIN_ENTRY_AMOUNT_LAMPORTS &&
|
|
130
|
+
amountLamports <= MAX_ENTRY_AMOUNT_LAMPORTS;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Live and deferred surfaces
|
|
79
134
|
|
|
80
|
-
|
|
81
|
-
before sensitive protocol material is sent. Verification failures stop the
|
|
82
|
-
session.
|
|
135
|
+
Live today:
|
|
83
136
|
|
|
84
|
-
|
|
137
|
+
- `createSession` opens a live WebSocket, runs Noise XX, verifies TDX attestation, and returns an
|
|
138
|
+
attested `Session`.
|
|
139
|
+
- `contractRequest`, `sync`, and `requestRefund` are the only normal-user command path over a
|
|
140
|
+
caller-owned attested session. `closeSession` ends the flow.
|
|
141
|
+
- LP lifecycle helpers drive position open/recover, DKG, funding, refill, withdrawal, confirmation,
|
|
142
|
+
and listing.
|
|
143
|
+
- Input validation throws typed `PolicyValidationError`; the closed `InvisibleError` taxonomy and
|
|
144
|
+
`normalizeError` are available to callers.
|
|
85
145
|
|
|
86
|
-
|
|
87
|
-
- protecting Recovery Codes and sync secrets;
|
|
88
|
-
- persisting recovery material before asking a user to deposit;
|
|
89
|
-
- using fresh payout destinations;
|
|
90
|
-
- handling reconnects through sync instead of blindly repeating commands.
|
|
146
|
+
Other target surfaces throw `NotImplementedError` until each is finalized. No command fakes success.
|
|
91
147
|
|
|
92
|
-
|
|
93
|
-
coordinator build; it does not prove that the code is bug-free. Privacy is not
|
|
94
|
-
absolute and can be weakened by low pool depth, timing, amount correlation,
|
|
95
|
-
destination reuse, and off-chain metadata.
|
|
148
|
+
## Recovery material and storage
|
|
96
149
|
|
|
97
|
-
|
|
98
|
-
|
|
150
|
+
The SDK does not persist recovery material automatically. Consumers that need restart or tab-close
|
|
151
|
+
recovery must store the relevant values themselves:
|
|
152
|
+
|
|
153
|
+
| Material | Needed for | Guidance |
|
|
154
|
+
| ----------------------- | ----------------------------------------------- | ------------------------------------------------------- |
|
|
155
|
+
| `swapId` + `syncSecret` | Re-sync a private-transfer status view | Persist before asking the user to deposit. |
|
|
156
|
+
| User Recovery Code | Request an origin-bound private-transfer refund | Treat it like a seed phrase and persist it immediately. |
|
|
157
|
+
| LP Position Code | Recover and operate an LP position | Keep it out of logs and treat it like a seed phrase. |
|
|
158
|
+
|
|
159
|
+
The web app persists private-transfer recovery material locally so users can resume flows. SDK
|
|
160
|
+
consumers can choose `browserStorage`, `extensionStorage`, or their own encrypted storage layer.
|
|
161
|
+
|
|
162
|
+
LP DKG requests are bounded. If a browser worker stops responding, the SDK terminates the local
|
|
163
|
+
workers and attempts the signed position-scoped DKG abort command within a bounded cleanup window
|
|
164
|
+
before returning the original failure. LP recovery sends the same cleanup command for an
|
|
165
|
+
incomplete position, so a reload does not wait for the coordinator's session expiry.
|
|
166
|
+
|
|
167
|
+
## Security model
|
|
168
|
+
|
|
169
|
+
The SDK establishes an encrypted Noise XX channel and verifies TDX attestation before sensitive
|
|
170
|
+
protocol material is sent. Verification failures stop the session. Integrators remain responsible
|
|
171
|
+
for loading coordinator measurements from an approved release source, protecting Recovery Codes and
|
|
172
|
+
sync secrets, persisting recovery material before deposit, using fresh payout destinations, and
|
|
173
|
+
handling reconnects through `sync` instead of blindly repeating commands.
|
|
174
|
+
|
|
175
|
+
Invisible is trust-minimized, not trustless. Attestation verifies an approved coordinator build; it
|
|
176
|
+
does not prove that the code is bug-free. Privacy can be weakened by low pool depth, timing, amount
|
|
177
|
+
correlation, destination reuse, and off-chain metadata.
|
|
99
178
|
|
|
100
179
|
## Devnet limitations
|
|
101
180
|
|
|
@@ -105,15 +184,52 @@ Read the full
|
|
|
105
184
|
- Availability and privacy strength depend on current pool conditions.
|
|
106
185
|
- Some documented target APIs are not yet available in the devnet beta.
|
|
107
186
|
|
|
108
|
-
Use only APIs marked as live in the
|
|
109
|
-
|
|
187
|
+
Use only APIs marked as live in the [current reference](https://docs.invisible.exchange/docs/sdk/reference/).
|
|
188
|
+
|
|
189
|
+
## Not in this SDK
|
|
190
|
+
|
|
191
|
+
Protocol-fee admin payout is out of scope for the SDK. It lives behind a separate admin surface.
|
|
192
|
+
|
|
193
|
+
## Packaging
|
|
194
|
+
|
|
195
|
+
The package is bundled with tsup into a self-contained artifact. Workspace-internal packages and the
|
|
196
|
+
FROST WASM are inlined into the published bundle, while published third-party packages remain
|
|
197
|
+
external dependencies.
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
npm run build:private
|
|
201
|
+
npm run verify:exports
|
|
202
|
+
npm run verify:private-artifact
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
The public artifact is built separately with approved release inputs:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
SDK_PRODUCTION_BINARY_HASH=<64-hex-binary-sha256> \
|
|
209
|
+
AZURE_PROD_EXPECTED_BINARY_HASH=<same-64-hex-binary-sha256> \
|
|
210
|
+
SDK_PRODUCTION_COORDINATOR_MRTD=<96-hex-mrtd> \
|
|
211
|
+
SDK_PRODUCTION_RUNTIME_PROFILE=prod-devnet-simplified \
|
|
212
|
+
npm run build:public
|
|
213
|
+
npm run verify:exports
|
|
214
|
+
npm run verify:public-build-marker
|
|
215
|
+
npm run verify:public-artifact
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The public production smoke consumes that already verified artifact. It requires
|
|
219
|
+
`--prebuilt-sdk` plus an operator-approved release manifest whose exact file
|
|
220
|
+
SHA-256 is supplied separately:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
SDK_APPROVED_RELEASE_MANIFEST_PATH=<approved-release-manifest> \
|
|
224
|
+
SDK_APPROVED_RELEASE_MANIFEST_SHA256=<sha256-of-manifest-bytes> \
|
|
225
|
+
npm --workspace @invisible-labs/sdk run smoke:prod-attestation -- \
|
|
226
|
+
--host tee-azure.invisible.exchange --mrtd <96-hex-mrtd> \
|
|
227
|
+
--binary-hash <64-hex-binary-sha256> --target public \
|
|
228
|
+
--runtime-profile prod-devnet-simplified --prebuilt-sdk
|
|
229
|
+
```
|
|
110
230
|
|
|
111
|
-
|
|
231
|
+
Do not pack the workspace directly. Use the private or public staged publish
|
|
232
|
+
commands so the selected build target and artifact marker are checked.
|
|
112
233
|
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
- [Examples](https://docs.invisible.exchange/docs/sdk/examples/)
|
|
116
|
-
- [API reference](https://docs.invisible.exchange/docs/sdk/reference/)
|
|
117
|
-
- [Compatibility](https://docs.invisible.exchange/docs/sdk/compatibility/)
|
|
118
|
-
- [Versioning](https://docs.invisible.exchange/docs/sdk/versioning/)
|
|
119
|
-
- [V0 launch scope](https://docs.invisible.exchange/docs/v0-launch/)
|
|
234
|
+
Private smoke runs may rebuild the private SDK. Public smoke must use
|
|
235
|
+
`--prebuilt-sdk` so it cannot rebuild after the public artifact gates.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"package": "@invisible-labs/sdk",
|
|
3
|
+
"target": "public",
|
|
4
|
+
"productionBinaryHash": "92237e1cc0d528a12288ff5a2d99eff38ab387080d31eb4146526daa6c973860",
|
|
5
|
+
"productionMrtd": "a2e61f1316e9e367e9c1f7a0adc98c48eb13875c399c85d286cee5ea2b05e57f2df9f61d903b0ae7ac5607d843dfffc1",
|
|
6
|
+
"productionRuntimeProfile": "prod-devnet-simplified"
|
|
7
|
+
}
|
|
@@ -6,12 +6,12 @@ var LP_DEFAULT_TARGET_SHARDS = 200;
|
|
|
6
6
|
var LP_MAX_TARGET_SHARDS = 300;
|
|
7
7
|
var LP_DEFAULT_REFILL_BATCH_SIZE = 50;
|
|
8
8
|
var LP_MAX_REFILL_BATCH_SIZE = 50;
|
|
9
|
-
var PRODUCT_MIN_ENTRY_LAMPORTS =
|
|
9
|
+
var PRODUCT_MIN_ENTRY_LAMPORTS = 15e8;
|
|
10
10
|
var PRODUCT_MAX_ENTRY_LAMPORTS = 1e11;
|
|
11
11
|
function isValidLpPositionId(lpPositionId) {
|
|
12
12
|
return lpPositionId.length >= LP_POSITION_ID_MIN_LENGTH && lpPositionId.length <= LP_POSITION_ID_MAX_LENGTH && LP_POSITION_ID_PATTERN.test(lpPositionId);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export { LP_DEFAULT_REFILL_BATCH_SIZE, LP_DEFAULT_TARGET_SHARDS, LP_MAX_REFILL_BATCH_SIZE, LP_MAX_TARGET_SHARDS, PRODUCT_MAX_ENTRY_LAMPORTS, PRODUCT_MIN_ENTRY_LAMPORTS, isValidLpPositionId };
|
|
16
|
-
//# sourceMappingURL=chunk-
|
|
17
|
-
//# sourceMappingURL=chunk-
|
|
16
|
+
//# sourceMappingURL=chunk-4X5OCCQW.js.map
|
|
17
|
+
//# sourceMappingURL=chunk-4X5OCCQW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../shared/src/index.ts"],"names":[],"mappings":";AAgBO,IAAM,yBAAA,GAA4B,CAAA;AAClC,IAAM,yBAAA,GAA4B,EAAA;AAClC,IAAM,sBAAA,GAAyB,kBAAA;AAC/B,IAAM,wBAAA,GAA2B;AACjC,IAAM,oBAAA,GAAuB;AAC7B,IAAM,4BAAA,GAA+B;AACrC,IAAM,wBAAA,GAA2B;AAKjC,IAAM,0BAAA,GAA6B;AACnC,IAAM,0BAAA,GAA6B;AAGnC,SAAS,oBAAoB,YAAA,EAA+B;AACjE,EAAA,OACE,YAAA,CAAa,UAAU,yBAAA,IACvB,YAAA,CAAa,UAAU,yBAAA,IACvB,sBAAA,CAAuB,KAAK,YAAY,CAAA;AAE5C","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../../shared/src/index.ts"],"names":[],"mappings":";AAgBO,IAAM,yBAAA,GAA4B,CAAA;AAClC,IAAM,yBAAA,GAA4B,EAAA;AAClC,IAAM,sBAAA,GAAyB,kBAAA;AAC/B,IAAM,wBAAA,GAA2B;AACjC,IAAM,oBAAA,GAAuB;AAC7B,IAAM,4BAAA,GAA+B;AACrC,IAAM,wBAAA,GAA2B;AAKjC,IAAM,0BAAA,GAA6B;AACnC,IAAM,0BAAA,GAA6B;AAGnC,SAAS,oBAAoB,YAAA,EAA+B;AACjE,EAAA,OACE,YAAA,CAAa,UAAU,yBAAA,IACvB,YAAA,CAAa,UAAU,yBAAA,IACvB,sBAAA,CAAuB,KAAK,YAAY,CAAA;AAE5C","file":"chunk-4X5OCCQW.js","sourcesContent":["/**\n * Shared workspace entrypoint.\n *\n * Keep exports here pure and reusable across workspaces. Do not put React,\n * DOM-only, libp2p runtime state, or feature-specific glue in this package.\n */\nexport function sleep(ms: number): Promise<void> {\n if (ms <= 0) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nexport const LP_POSITION_ID_MIN_LENGTH = 3;\nexport const LP_POSITION_ID_MAX_LENGTH = 96;\nexport const LP_POSITION_ID_PATTERN = /^[A-Za-z0-9_-]+$/;\nexport const LP_DEFAULT_TARGET_SHARDS = 200;\nexport const LP_MAX_TARGET_SHARDS = 300;\nexport const LP_DEFAULT_REFILL_BATCH_SIZE = 50;\nexport const LP_MAX_REFILL_BATCH_SIZE = 50;\n\n// Temporary TypeScript mirrors of the Rust TEE entry limits, plus the distinct\n// mainnet UI default. Keep them guarded by `npm run product-limits:check` until\n// cross-language generated product constants exist.\nexport const PRODUCT_MIN_ENTRY_LAMPORTS = 1_500_000_000;\nexport const PRODUCT_MAX_ENTRY_LAMPORTS = 100_000_000_000;\nexport const PRODUCT_DEFAULT_MAINNET_ENTRY_LAMPORTS = 1_500_000_000;\n\nexport function isValidLpPositionId(lpPositionId: string): boolean {\n return (\n lpPositionId.length >= LP_POSITION_ID_MIN_LENGTH &&\n lpPositionId.length <= LP_POSITION_ID_MAX_LENGTH &&\n LP_POSITION_ID_PATTERN.test(lpPositionId)\n );\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { failSessionClosed, createSessionHandle, getSessionState, closeSessionState } from './chunk-
|
|
2
|
-
import { verifyAttestation, assertAttestResponse } from './chunk-
|
|
3
|
-
import { TransportError, AttestationError } from './chunk-
|
|
1
|
+
import { failSessionClosed, createSessionHandle, getSessionState, closeSessionState } from './chunk-V5HXJRBW.js';
|
|
2
|
+
import { verifyAttestation, assertAttestResponse } from './chunk-DIA6U2CV.js';
|
|
3
|
+
import { TransportError, AttestationError } from './chunk-GHBQF3A7.js';
|
|
4
4
|
import { generateKeyPair, sharedKey } from '@stablelib/x25519';
|
|
5
5
|
import { ChaCha20Poly1305 } from '@stablelib/chacha20poly1305';
|
|
6
6
|
import { hash, SHA256 } from '@stablelib/sha256';
|
|
@@ -398,6 +398,7 @@ function toAttestationPolicy(endpoint) {
|
|
|
398
398
|
// ignore the MRTD pin inside the verifier.
|
|
399
399
|
expectedMrtd: pin.mrtd,
|
|
400
400
|
...pin.binaryHash ? { expectedBinaryHash: pin.binaryHash } : {},
|
|
401
|
+
...pin.runtimeProfile ? { expectedRuntimeProfile: pin.runtimeProfile } : {},
|
|
401
402
|
allowMissingDcapCollateral: pin.allowMissingDcapCollateral === true,
|
|
402
403
|
allowLocalAttestation
|
|
403
404
|
};
|
|
@@ -694,6 +695,7 @@ async function establishAttestedChannel(params) {
|
|
|
694
695
|
mrtd: channel.attestation.mrtd,
|
|
695
696
|
mode: channel.attestation.mode,
|
|
696
697
|
binaryHash: channel.attestation.binaryHash,
|
|
698
|
+
runtimeProfile: channel.attestation.runtimeProfile,
|
|
697
699
|
pubkeyHex: channel.attestation.pubkeyHex,
|
|
698
700
|
localAttestation: channel.attestation.localAttestation,
|
|
699
701
|
rtmr0: channel.attestation.rtmr0,
|
|
@@ -705,33 +707,6 @@ async function establishAttestedChannel(params) {
|
|
|
705
707
|
void toAttestationPolicy(endpoint);
|
|
706
708
|
return { channel, handshake, attestation };
|
|
707
709
|
}
|
|
708
|
-
async function performNoiseHandshake(transport, endpoint, nonce = crypto.getRandomValues(new Uint8Array(32))) {
|
|
709
|
-
const established = await establishAttestedChannel({ transport, endpoint, nonce });
|
|
710
|
-
return established.handshake;
|
|
711
|
-
}
|
|
712
|
-
function performAttestation(_transport, handshake) {
|
|
713
|
-
const channel = handshake.channel;
|
|
714
|
-
if (!channel) {
|
|
715
|
-
return Promise.reject(
|
|
716
|
-
new TransportError(
|
|
717
|
-
"NOISE_HANDSHAKE_FAILED",
|
|
718
|
-
"performAttestation requires a handshake result produced by performNoiseHandshake"
|
|
719
|
-
)
|
|
720
|
-
);
|
|
721
|
-
}
|
|
722
|
-
return Promise.resolve({
|
|
723
|
-
mrtd: channel.attestation.mrtd,
|
|
724
|
-
mode: channel.attestation.mode,
|
|
725
|
-
binaryHash: channel.attestation.binaryHash,
|
|
726
|
-
pubkeyHex: channel.attestation.pubkeyHex,
|
|
727
|
-
localAttestation: channel.attestation.localAttestation,
|
|
728
|
-
rtmr0: channel.attestation.rtmr0,
|
|
729
|
-
rtmr1: channel.attestation.rtmr1,
|
|
730
|
-
rtmr2: channel.attestation.rtmr2,
|
|
731
|
-
rtmr3: channel.attestation.rtmr3,
|
|
732
|
-
verifiedAtMs: Date.now()
|
|
733
|
-
});
|
|
734
|
-
}
|
|
735
710
|
|
|
736
711
|
// src/schemas/payoutPolicy.schema.json
|
|
737
712
|
var payoutPolicy_schema_default = {
|
|
@@ -872,6 +847,10 @@ var coordinatorPoolConfig_schema_default = {
|
|
|
872
847
|
pattern: "^[0-9a-fA-F]{64}$",
|
|
873
848
|
description: "Optional SHA-256 hash of the approved coordinator binary; required for production Azure attestation."
|
|
874
849
|
},
|
|
850
|
+
runtimeProfile: {
|
|
851
|
+
enum: ["prod-hardened", "prod-devnet-simplified"],
|
|
852
|
+
description: "Optional compile-time coordinator runtime profile; production simplified deployments must pin it."
|
|
853
|
+
},
|
|
875
854
|
intelRootFingerprint: {
|
|
876
855
|
type: "string",
|
|
877
856
|
description: "Hex SHA-256 of the Intel root cert."
|
|
@@ -1023,6 +1002,7 @@ async function reattest(state, endpoint, timeoutMs = DEFAULT_REATTEST_TIMEOUT_MS
|
|
|
1023
1002
|
mrtd: metadata.mrtd,
|
|
1024
1003
|
mode: metadata.mode,
|
|
1025
1004
|
binaryHash: metadata.binaryHash,
|
|
1005
|
+
runtimeProfile: metadata.runtimeProfile,
|
|
1026
1006
|
pubkeyHex: metadata.pubkeyHex,
|
|
1027
1007
|
localAttestation: metadata.localAttestation,
|
|
1028
1008
|
rtmr0: metadata.rtmr0,
|
|
@@ -1052,7 +1032,7 @@ function toHex(b) {
|
|
|
1052
1032
|
|
|
1053
1033
|
// src/session/createSession.ts
|
|
1054
1034
|
var REATTEST_EVERY_MS = 9e5;
|
|
1055
|
-
async function
|
|
1035
|
+
async function createSessionInternal(options) {
|
|
1056
1036
|
const { coordinator } = options;
|
|
1057
1037
|
if (!validateCoordinatorPoolConfigShape(coordinator)) {
|
|
1058
1038
|
throw new Error(
|
|
@@ -1063,11 +1043,15 @@ async function createSession(options) {
|
|
|
1063
1043
|
assertExpectedHostname(endpoint);
|
|
1064
1044
|
const timeoutMs = coordinator.noiseTransportTimeoutMs;
|
|
1065
1045
|
const transport = options.transport ?? noiseWebSocketTransport({ wsUrl: endpoint.wsUrl, connectTimeoutMs: timeoutMs });
|
|
1066
|
-
await transport.connect();
|
|
1046
|
+
await transport.connect(options.signal);
|
|
1067
1047
|
const nonce = crypto.getRandomValues(new Uint8Array(32));
|
|
1068
1048
|
let established;
|
|
1069
1049
|
try {
|
|
1070
|
-
established = await
|
|
1050
|
+
established = await abortableSessionEstablishment(
|
|
1051
|
+
establishAttestedChannel({ transport, endpoint, nonce, timeoutMs }),
|
|
1052
|
+
transport,
|
|
1053
|
+
options.signal
|
|
1054
|
+
);
|
|
1071
1055
|
} catch (err) {
|
|
1072
1056
|
transport.close();
|
|
1073
1057
|
throw err;
|
|
@@ -1092,6 +1076,27 @@ async function createSession(options) {
|
|
|
1092
1076
|
scheduleReattest(state, endpoint);
|
|
1093
1077
|
return createSessionHandle(state);
|
|
1094
1078
|
}
|
|
1079
|
+
function abortableSessionEstablishment(establishment, transport, signal) {
|
|
1080
|
+
if (signal === void 0) return establishment;
|
|
1081
|
+
if (signal.aborted) {
|
|
1082
|
+
transport.close();
|
|
1083
|
+
return Promise.reject(createSessionAbortError());
|
|
1084
|
+
}
|
|
1085
|
+
return new Promise((resolve, reject) => {
|
|
1086
|
+
const onAbort = () => {
|
|
1087
|
+
transport.close();
|
|
1088
|
+
reject(createSessionAbortError());
|
|
1089
|
+
};
|
|
1090
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1091
|
+
void establishment.then(resolve, reject).finally(() => {
|
|
1092
|
+
signal.removeEventListener("abort", onAbort);
|
|
1093
|
+
});
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
function createSessionAbortError() {
|
|
1097
|
+
return new TransportError("CONNECTION_LOST", "session establishment aborted");
|
|
1098
|
+
}
|
|
1099
|
+
var createSession = createSessionInternal;
|
|
1095
1100
|
function assertExpectedHostname(endpoint) {
|
|
1096
1101
|
let hostname;
|
|
1097
1102
|
try {
|
|
@@ -1140,6 +1145,6 @@ async function runReattest(state, endpoint) {
|
|
|
1140
1145
|
}
|
|
1141
1146
|
}
|
|
1142
1147
|
|
|
1143
|
-
export { closeSession, createExponentialBackoff, createSession, createStateController, formatAjvErrors,
|
|
1144
|
-
//# sourceMappingURL=chunk-
|
|
1145
|
-
//# sourceMappingURL=chunk-
|
|
1148
|
+
export { closeSession, createExponentialBackoff, createSession, createSessionInternal, createStateController, formatAjvErrors, isLoopbackUrl, noiseWebSocketTransport, reattestSerialized, validatePayoutPolicyShape };
|
|
1149
|
+
//# sourceMappingURL=chunk-5NNEO7IK.js.map
|
|
1150
|
+
//# sourceMappingURL=chunk-5NNEO7IK.js.map
|