@lifi/perps-sdk-provider-ondo 1.0.0 → 1.0.2
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 +43 -28
- package/dist/cjs/OndoProvider.d.ts.map +1 -1
- package/dist/cjs/OndoProvider.js +6 -2
- package/dist/cjs/OndoProvider.js.map +1 -1
- package/dist/cjs/auth/OndoApiKeyStore.d.ts +1 -0
- package/dist/cjs/auth/OndoApiKeyStore.d.ts.map +1 -1
- package/dist/cjs/auth/OndoApiKeyStore.js +3 -2
- package/dist/cjs/auth/OndoApiKeyStore.js.map +1 -1
- package/dist/cjs/auth/OndoTokenStore.d.ts.map +1 -1
- package/dist/cjs/auth/OndoTokenStore.js +2 -3
- package/dist/cjs/auth/OndoTokenStore.js.map +1 -1
- package/dist/cjs/auth/signActions.d.ts +1 -1
- package/dist/cjs/auth/signActions.d.ts.map +1 -1
- package/dist/cjs/auth/signActions.js +16 -7
- package/dist/cjs/auth/signActions.js.map +1 -1
- package/dist/cjs/types/auth.d.ts +0 -1
- package/dist/cjs/types/auth.d.ts.map +1 -1
- package/dist/cjs/types/wire.d.ts +7 -0
- package/dist/cjs/types/wire.d.ts.map +1 -1
- package/dist/cjs/websocket/OndoWsProvider.d.ts +3 -0
- package/dist/cjs/websocket/OndoWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/OndoWsProvider.js +55 -11
- package/dist/cjs/websocket/OndoWsProvider.js.map +1 -1
- package/dist/esm/OndoProvider.d.ts.map +1 -1
- package/dist/esm/OndoProvider.js +7 -3
- package/dist/esm/OndoProvider.js.map +1 -1
- package/dist/esm/auth/OndoApiKeyStore.d.ts +3 -1
- package/dist/esm/auth/OndoApiKeyStore.d.ts.map +1 -1
- package/dist/esm/auth/OndoApiKeyStore.js +3 -2
- package/dist/esm/auth/OndoApiKeyStore.js.map +1 -1
- package/dist/esm/auth/OndoTokenStore.d.ts.map +1 -1
- package/dist/esm/auth/OndoTokenStore.js +2 -3
- package/dist/esm/auth/OndoTokenStore.js.map +1 -1
- package/dist/esm/auth/signActions.d.ts +2 -2
- package/dist/esm/auth/signActions.d.ts.map +1 -1
- package/dist/esm/auth/signActions.js +29 -12
- package/dist/esm/auth/signActions.js.map +1 -1
- package/dist/esm/types/auth.d.ts +0 -2
- package/dist/esm/types/auth.d.ts.map +1 -1
- package/dist/esm/types/wire.d.ts +12 -0
- package/dist/esm/types/wire.d.ts.map +1 -1
- package/dist/esm/websocket/OndoWsProvider.d.ts +19 -0
- package/dist/esm/websocket/OndoWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/OndoWsProvider.js +84 -16
- package/dist/esm/websocket/OndoWsProvider.js.map +1 -1
- package/dist/types/OndoProvider.d.ts.map +1 -1
- package/dist/types/auth/OndoApiKeyStore.d.ts +3 -1
- package/dist/types/auth/OndoApiKeyStore.d.ts.map +1 -1
- package/dist/types/auth/OndoTokenStore.d.ts.map +1 -1
- package/dist/types/auth/signActions.d.ts +2 -2
- package/dist/types/auth/signActions.d.ts.map +1 -1
- package/dist/types/types/auth.d.ts +0 -2
- package/dist/types/types/auth.d.ts.map +1 -1
- package/dist/types/types/wire.d.ts +12 -0
- package/dist/types/types/wire.d.ts.map +1 -1
- package/dist/types/websocket/OndoWsProvider.d.ts +19 -0
- package/dist/types/websocket/OndoWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/OndoProvider.ts +10 -2
- package/src/auth/OndoApiKeyStore.ts +3 -2
- package/src/auth/OndoTokenStore.ts +1 -3
- package/src/auth/signActions.ts +33 -12
- package/src/types/auth.ts +0 -2
- package/src/types/wire.ts +13 -0
- package/src/websocket/OndoWsProvider.ts +90 -21
|
@@ -70,6 +70,13 @@ const ONDO_AUTH_CHANNEL = {
|
|
|
70
70
|
|
|
71
71
|
type AuthChannel = keyof typeof ONDO_AUTH_CHANNEL
|
|
72
72
|
|
|
73
|
+
// Fan-out channels that reserve the connection's single authenticated-address
|
|
74
|
+
// binding; `accountSummary` rides the auth wires without being one itself.
|
|
75
|
+
const ONDO_AUTH_FANOUT: readonly string[] = [
|
|
76
|
+
...Object.keys(ONDO_AUTH_CHANNEL),
|
|
77
|
+
'accountSummary',
|
|
78
|
+
]
|
|
79
|
+
|
|
73
80
|
const isAuthChannel = (
|
|
74
81
|
channel: Subscription['channel']
|
|
75
82
|
): channel is AuthChannel => channel in ONDO_AUTH_CHANNEL
|
|
@@ -157,9 +164,11 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
157
164
|
)
|
|
158
165
|
this.client = client
|
|
159
166
|
this.registry = client && getMarketRegistry(client, providerKey)
|
|
160
|
-
// The venue's login lives and dies with the connection
|
|
167
|
+
// The venue's login lives and dies with the connection, so a drop must
|
|
168
|
+
// forget both the in-flight login and the address it bound.
|
|
161
169
|
this.rws.on('close', () => {
|
|
162
170
|
this.loginPromise = undefined
|
|
171
|
+
this.accountAddress = undefined
|
|
163
172
|
})
|
|
164
173
|
}
|
|
165
174
|
|
|
@@ -217,31 +226,35 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
217
226
|
const needsLogin =
|
|
218
227
|
isAuthChannel(sub.channel) || sub.channel === 'accountSummary'
|
|
219
228
|
|
|
229
|
+
let boundHere = false
|
|
220
230
|
if (needsLogin) {
|
|
221
|
-
// One login per connection means one authenticated address.
|
|
222
231
|
const address = (sub as { address: Address }).address.toLowerCase()
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
this.accountAddress !== address
|
|
226
|
-
) {
|
|
227
|
-
throw new Error(
|
|
228
|
-
`Ondo WS supports one authenticated address per connection; already bound to ${this.accountAddress}, cannot subscribe for ${address}.`
|
|
229
|
-
)
|
|
230
|
-
}
|
|
231
|
-
this.accountAddress = address
|
|
232
|
-
// Account frames carry venue market symbols; the registry supplies the
|
|
233
|
-
// market identity the mapped orders/fills/positions embed.
|
|
234
|
-
await this.registry?.sync()
|
|
232
|
+
boundHere = this.accountAddress !== address
|
|
233
|
+
this.bindAddress(address)
|
|
235
234
|
}
|
|
236
235
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
236
|
+
try {
|
|
237
|
+
if (needsLogin) {
|
|
238
|
+
// Account frames carry venue market symbols; the registry supplies the
|
|
239
|
+
// market identity the mapped orders/fills/positions embed.
|
|
240
|
+
await this.registry?.sync()
|
|
241
|
+
}
|
|
242
|
+
if (sub.channel === 'accountSummary') {
|
|
243
|
+
await this.seedAccountSummary((sub as { address: Address }).address)
|
|
244
|
+
}
|
|
245
|
+
// Authenticated wire subs are shared and ref-counted; public ones are 1:1.
|
|
246
|
+
for (const [key, state] of wireSubs) {
|
|
247
|
+
await this.acquireWire(key, state, needsLogin)
|
|
248
|
+
}
|
|
249
|
+
await this.rws.ready()
|
|
250
|
+
} catch (err) {
|
|
251
|
+
// Login/seed failed before the binding took hold on the wire: release a
|
|
252
|
+
// binding this call newly reserved so a later subscribe can rebind.
|
|
253
|
+
if (boundHere) {
|
|
254
|
+
this.accountAddress = undefined
|
|
255
|
+
}
|
|
256
|
+
throw err
|
|
243
257
|
}
|
|
244
|
-
await this.rws.ready()
|
|
245
258
|
|
|
246
259
|
return () => {
|
|
247
260
|
if (sub.channel === 'accountSummary') {
|
|
@@ -253,6 +266,53 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
253
266
|
}
|
|
254
267
|
}
|
|
255
268
|
|
|
269
|
+
/**
|
|
270
|
+
* Reserve the connection's single authenticated slot for `address`. A prior
|
|
271
|
+
* binding whose channels have all been released — still lingering in the
|
|
272
|
+
* base teardown window — is reclaimed (cycling the connection) before the
|
|
273
|
+
* new one takes it; a binding that another address still holds live throws.
|
|
274
|
+
*/
|
|
275
|
+
private bindAddress(address: string): void {
|
|
276
|
+
if (this.accountAddress === address) {
|
|
277
|
+
return
|
|
278
|
+
}
|
|
279
|
+
if (this.accountAddress !== undefined && !this.releaseBindingIfIdle()) {
|
|
280
|
+
throw new Error(
|
|
281
|
+
`Ondo WS supports one authenticated address per connection; already bound to ${this.accountAddress}, cannot subscribe for ${address}.`
|
|
282
|
+
)
|
|
283
|
+
}
|
|
284
|
+
this.accountAddress = address
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Force-tear-down the bound address's authenticated channels when every one
|
|
289
|
+
* is idle, which cycles the connection via {@link releaseBinding}. Returns
|
|
290
|
+
* false — leaving the binding intact — while any is still live.
|
|
291
|
+
*/
|
|
292
|
+
private releaseBindingIfIdle(): boolean {
|
|
293
|
+
const bound = this.accountAddress
|
|
294
|
+
if (bound === undefined) {
|
|
295
|
+
return true
|
|
296
|
+
}
|
|
297
|
+
for (const channel of ONDO_AUTH_FANOUT) {
|
|
298
|
+
if (!this.closeChannelIfIdle(`${channel}:${bound}`)) {
|
|
299
|
+
return false
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return true
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Forget the authenticated binding and cycle the connection. The venue
|
|
307
|
+
* permits one login per socket, so a later subscribe for a different address
|
|
308
|
+
* must authenticate on a fresh connection rather than re-login on this one.
|
|
309
|
+
*/
|
|
310
|
+
private releaseBinding(): void {
|
|
311
|
+
this.accountAddress = undefined
|
|
312
|
+
this.loginPromise = undefined
|
|
313
|
+
this.rws.reconnect()
|
|
314
|
+
}
|
|
315
|
+
|
|
256
316
|
/** Register a wire sub, ref-counting the shared authenticated channels. */
|
|
257
317
|
private async acquireWire(
|
|
258
318
|
key: string,
|
|
@@ -288,10 +348,18 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
288
348
|
}
|
|
289
349
|
this.unregisterSub(key)
|
|
290
350
|
this.rws.send(JSON.stringify({ op: 'unsubscribe', ...state.frame }))
|
|
351
|
+
// Last authenticated wire gone: forget the binding and cycle the socket so
|
|
352
|
+
// the next address logs in on a fresh connection.
|
|
353
|
+
if (shared && this.authWireRefs.size === 0) {
|
|
354
|
+
this.releaseBinding()
|
|
355
|
+
}
|
|
291
356
|
}
|
|
292
357
|
|
|
293
358
|
protected async sendSubscribe(state: SubState): Promise<void> {
|
|
294
359
|
if (state.needsAuth && state.address !== undefined) {
|
|
360
|
+
// Re-assert the binding: a replay after a reconnect (which cleared it on
|
|
361
|
+
// close) must restore the address account frames emit under.
|
|
362
|
+
this.accountAddress = state.address.toLowerCase()
|
|
295
363
|
await this.ensureLogin(state.address)
|
|
296
364
|
}
|
|
297
365
|
this.rws.send(JSON.stringify({ op: 'subscribe', ...state.frame }))
|
|
@@ -301,6 +369,7 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
301
369
|
this.contexts = {}
|
|
302
370
|
this.pendingFunding.clear()
|
|
303
371
|
this.loginPromise = undefined
|
|
372
|
+
this.accountAddress = undefined
|
|
304
373
|
}
|
|
305
374
|
|
|
306
375
|
/** Wire subs for `sub`, keyed uniquely for the base's replay registry. */
|