@lifi/perps-sdk 10.1.0 → 10.2.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.
Files changed (50) hide show
  1. package/dist/cjs/client/PerpsClient.d.ts +1 -1
  2. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  3. package/dist/cjs/client/PerpsClient.js +30 -16
  4. package/dist/cjs/client/PerpsClient.js.map +1 -1
  5. package/dist/cjs/index.d.ts +1 -1
  6. package/dist/cjs/index.d.ts.map +1 -1
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/types/api.d.ts +6 -1
  9. package/dist/cjs/types/api.d.ts.map +1 -1
  10. package/dist/cjs/types/provider.d.ts +1 -0
  11. package/dist/cjs/types/provider.d.ts.map +1 -1
  12. package/dist/cjs/utils/setupActions.d.ts.map +1 -1
  13. package/dist/cjs/utils/setupActions.js.map +1 -1
  14. package/dist/cjs/version.d.ts +1 -1
  15. package/dist/cjs/version.js +1 -1
  16. package/dist/esm/client/PerpsClient.d.ts +13 -8
  17. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  18. package/dist/esm/client/PerpsClient.js +47 -23
  19. package/dist/esm/client/PerpsClient.js.map +1 -1
  20. package/dist/esm/index.d.ts +1 -1
  21. package/dist/esm/index.d.ts.map +1 -1
  22. package/dist/esm/index.js.map +1 -1
  23. package/dist/esm/types/api.d.ts +22 -1
  24. package/dist/esm/types/api.d.ts.map +1 -1
  25. package/dist/esm/types/provider.d.ts +9 -0
  26. package/dist/esm/types/provider.d.ts.map +1 -1
  27. package/dist/esm/utils/setupActions.d.ts +4 -3
  28. package/dist/esm/utils/setupActions.d.ts.map +1 -1
  29. package/dist/esm/utils/setupActions.js +4 -3
  30. package/dist/esm/utils/setupActions.js.map +1 -1
  31. package/dist/esm/version.d.ts +1 -1
  32. package/dist/esm/version.js +1 -1
  33. package/dist/types/client/PerpsClient.d.ts +13 -8
  34. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  35. package/dist/types/index.d.ts +1 -1
  36. package/dist/types/index.d.ts.map +1 -1
  37. package/dist/types/types/api.d.ts +22 -1
  38. package/dist/types/types/api.d.ts.map +1 -1
  39. package/dist/types/types/provider.d.ts +9 -0
  40. package/dist/types/types/provider.d.ts.map +1 -1
  41. package/dist/types/utils/setupActions.d.ts +4 -3
  42. package/dist/types/utils/setupActions.d.ts.map +1 -1
  43. package/dist/types/version.d.ts +1 -1
  44. package/package.json +1 -1
  45. package/src/client/PerpsClient.ts +64 -30
  46. package/src/index.ts +1 -0
  47. package/src/types/api.ts +23 -0
  48. package/src/types/provider.ts +10 -0
  49. package/src/utils/setupActions.ts +4 -3
  50. package/src/version.ts +1 -1
@@ -582,6 +582,9 @@ export class PerpsClient {
582
582
  /**
583
583
  * Return the unsatisfied entries on `Provider.setup` for this account as a
584
584
  * flat, self-describing list. Trading is gated on `isReady === true`.
585
+ * `checklist` carries the renderable onboarding list: every USER-signed
586
+ * descriptor with its satisfied state, with not-required conditional steps
587
+ * omitted.
585
588
  *
586
589
  * `Provider.options` descriptors are NEVER returned here — options are
587
590
  * post-setup tunables and never gate trading. Option state is surfaced
@@ -603,7 +606,12 @@ export class PerpsClient {
603
606
  // SIWE-first providers (Ondo) are the exception: they cannot reliably probe
604
607
  // account existence before the user signs in, so setup must still stage.
605
608
  if (!hasSiweSetup && !(await this.accountExists(provider, address))) {
606
- return { accountExists: false, setup: [], isReady: false }
609
+ return {
610
+ accountExists: false,
611
+ setup: [],
612
+ isReady: false,
613
+ checklist: [],
614
+ }
607
615
  }
608
616
 
609
617
  const satisfiedSetup = await this.resolveSatisfiedSetup(provider, address)
@@ -611,13 +619,13 @@ export class PerpsClient {
611
619
  (descriptor) => !satisfiedSetup.has(descriptor.type)
612
620
  )
613
621
 
614
- const hiddenSetup = await this.resolveInternalSetup(
615
- provider,
616
- address,
617
- pendingSetup
618
- )
622
+ const plugin = this.sdkClient.getProvider(provider)
623
+ const internalTypes = new Set(plugin?.internalSetupActions ?? [])
624
+ const isInternal = (descriptor: ProviderAction): boolean =>
625
+ internalTypes.has(descriptor.type) &&
626
+ !descriptor.signers.includes(PerpsSigner.USER)
619
627
  const visibleSetup = pendingSetup.filter(
620
- (descriptor) => !hiddenSetup.has(descriptor.type)
628
+ (descriptor) => !isInternal(descriptor)
621
629
  )
622
630
 
623
631
  // The backend filters already-satisfied setup actions and returns typed
@@ -629,10 +637,38 @@ export class PerpsClient {
629
637
  visibleSetup
630
638
  )
631
639
 
640
+ // A staged step is one the build produced actions for — a pending
641
+ // descriptor the backend staged nothing for is either satisfied
642
+ // (backend-gated) or not applicable to this account.
643
+ const stagedTypes = new Set(actions.map((step) => step.action))
644
+ const conditionalTypes = new Set(plugin?.conditionalSetupActions ?? [])
645
+ const sequenceOf = (descriptor: ProviderAction): number =>
646
+ descriptor.sequence ?? Number.MAX_SAFE_INTEGER
647
+ const checklist = metadata.setup
648
+ .filter((descriptor) => descriptor.signers.includes(PerpsSigner.USER))
649
+ .filter(
650
+ (descriptor) =>
651
+ !conditionalTypes.has(descriptor.type) ||
652
+ stagedTypes.has(descriptor.type)
653
+ )
654
+ .sort((a, b) => sequenceOf(a) - sequenceOf(b))
655
+ .map((descriptor) => ({
656
+ descriptor,
657
+ satisfied: !stagedTypes.has(descriptor.type),
658
+ }))
659
+
660
+ await this.drainInternalSetup(
661
+ provider,
662
+ address,
663
+ pendingSetup.filter(isInternal),
664
+ visibleSetup.filter((descriptor) => stagedTypes.has(descriptor.type))
665
+ )
666
+
632
667
  return {
633
668
  accountExists: true,
634
669
  setup: actions,
635
670
  isReady: actions.length === 0,
671
+ checklist,
636
672
  }
637
673
  }
638
674
 
@@ -668,33 +704,32 @@ export class PerpsClient {
668
704
 
669
705
  /**
670
706
  * Drain the pending setup steps the provider declares as internal via
671
- * `PerpsProviderPlugin.internalSetupActions`, returning the set of action
672
- * types to omit from the caller-facing setup list. Each such step is built,
673
- * signed, and executed in place with the provider's own credentials. A
674
- * descriptor whose `signers` include {@link PerpsSigner.USER} is left to
675
- * render as a normal step. A drain failure is swallowed so it never blocks
676
- * setup — the step stays unsatisfied and is retried on a later `checkSetup`.
707
+ * `PerpsProviderPlugin.internalSetupActions`. Each step is built, signed,
708
+ * and executed in place with the provider's own credentials. A step is
709
+ * deferred while any staged user-facing step with a lower `sequence` is
710
+ * outstanding — it cannot succeed before its prerequisite (e.g. SET_REFERRAL
711
+ * authenticates with the credential REGISTER_API_KEY installs) and each
712
+ * doomed attempt is venue traffic. A drain failure is swallowed so it never
713
+ * blocks setup — the step stays unsatisfied and is retried on a later
714
+ * `checkSetup`.
677
715
  */
678
- private async resolveInternalSetup(
716
+ private async drainInternalSetup(
679
717
  provider: string,
680
718
  address: Address,
681
- pending: ProviderAction[]
682
- ): Promise<Set<ActionType>> {
683
- const plugin = this.sdkClient.getProvider(provider)
684
- const internal = plugin?.internalSetupActions
685
- if (!internal || internal.length === 0) {
686
- return new Set()
687
- }
688
- const internalTypes = new Set(internal)
689
- const hidden = new Set<ActionType>()
690
- for (const descriptor of pending) {
691
- if (
692
- !internalTypes.has(descriptor.type) ||
693
- descriptor.signers.includes(PerpsSigner.USER)
694
- ) {
719
+ internalPending: ProviderAction[],
720
+ stagedVisible: ProviderAction[]
721
+ ): Promise<void> {
722
+ const sequenceOf = (descriptor: ProviderAction): number =>
723
+ descriptor.sequence ?? Number.MAX_SAFE_INTEGER
724
+ for (const descriptor of internalPending) {
725
+ // A tie (equal sequences, or both absent) declares no order, so the
726
+ // internal step defers to the next checkSetup rather than racing.
727
+ const blocked = stagedVisible.some(
728
+ (staged) => sequenceOf(staged) <= sequenceOf(descriptor)
729
+ )
730
+ if (blocked) {
695
731
  continue
696
732
  }
697
- hidden.add(descriptor.type)
698
733
  try {
699
734
  const steps = await this.buildProviderSetupActions(provider, address, [
700
735
  descriptor,
@@ -721,7 +756,6 @@ export class PerpsClient {
721
756
  )
722
757
  }
723
758
  }
724
- return hidden
725
759
  }
726
760
 
727
761
  /**
package/src/index.ts CHANGED
@@ -117,6 +117,7 @@ export type {
117
117
  PlaceTwapOrderParams as ClientPlaceTwapOrderParams,
118
118
  ProviderSetup,
119
119
  SendAssetActionParams,
120
+ SetupChecklistItem,
120
121
  SubmitOnboardingParams,
121
122
  WithdrawParams,
122
123
  } from './types/api.js'
package/src/types/api.ts CHANGED
@@ -14,6 +14,7 @@ import type {
14
14
  OnboardParams,
15
15
  OrderSide,
16
16
  OrderType,
17
+ ProviderAction,
17
18
  SignedActionStep,
18
19
  TimeInForce,
19
20
  TriggerOrderInput,
@@ -287,6 +288,19 @@ export interface GetWithdrawableBalancesParams {
287
288
  address: Address
288
289
  }
289
290
 
291
+ /**
292
+ * One entry on {@link ProviderSetup.checklist}: a user-facing setup
293
+ * descriptor plus its satisfied state for the queried account.
294
+ *
295
+ * @public
296
+ */
297
+ export interface SetupChecklistItem {
298
+ /** The `Provider.setup` descriptor for this step. */
299
+ descriptor: ProviderAction
300
+ /** Whether the step is already satisfied for this account. */
301
+ satisfied: boolean
302
+ }
303
+
290
304
  /**
291
305
  * Result from {@link PerpsClient.checkSetup}.
292
306
  *
@@ -312,6 +326,15 @@ export interface ProviderSetup {
312
326
  setup: ActionStep[]
313
327
  /** Whether all setup items are already satisfied (ready to trade) */
314
328
  isReady: boolean
329
+ /**
330
+ * The renderable onboarding list: every USER-signed setup descriptor with
331
+ * its satisfied state, ordered by `sequence`. SDK-internal steps and
332
+ * conditional steps that staged no work for this account (see
333
+ * `PerpsProviderPlugin.conditionalSetupActions`) are omitted. Consumers
334
+ * render this list directly instead of joining `Provider.setup` metadata
335
+ * with the staged `setup` steps.
336
+ */
337
+ checklist: SetupChecklistItem[]
315
338
  }
316
339
 
317
340
  /**
@@ -358,6 +358,16 @@ export interface PerpsProviderPlugin {
358
358
  */
359
359
  readonly internalSetupActions?: readonly ActionType[]
360
360
 
361
+ /**
362
+ * Setup actions that stage work only when the account needs remediation
363
+ * (e.g. Hyperliquid's REVOKE_AGENT frees an agent slot only when every
364
+ * named slot is taken). When such a step stages no actions,
365
+ * `PerpsClient.checkSetup` omits it from `ProviderSetup.checklist` instead
366
+ * of rendering it as satisfied. Omit when every setup step is
367
+ * unconditional.
368
+ */
369
+ readonly conditionalSetupActions?: readonly ActionType[]
370
+
361
371
  /**
362
372
  * Inject the runtime {@link PerpsSDKClient} into the plugin once, during
363
373
  * {@link createPerpsClient}. The plugin captures it (config, fetch, retry,
@@ -8,9 +8,10 @@ import { PerpsSigner } from '@lifi/perps-types'
8
8
  * them inline, so surfacing them would render inert cards the user can't act on.
9
9
  *
10
10
  * Membership is a property of the descriptor's `signers` alone, independent of
11
- * any account: use this to build the onboarding list, then layer each entry's
12
- * satisfied/unsatisfied state on top from a live `checkSetup` so the tick never
13
- * goes stale.
11
+ * any account. When an account is available, prefer `ProviderSetup.checklist`
12
+ * from `checkSetup` for the onboarding list — it applies this filter, omits
13
+ * not-required conditional steps, and carries each entry's satisfied state.
14
+ * This function remains the static, account-free projection.
14
15
  *
15
16
  * @param setup The provider's `setup` descriptors, in their declared order.
16
17
  * @public
package/src/version.ts CHANGED
@@ -10,4 +10,4 @@ export const name = '@lifi/perps-sdk'
10
10
  *
11
11
  * @public
12
12
  */
13
- export const version = '10.1.0'
13
+ export const version = '10.2.0'