@lifi/perps-sdk 18.1.0 → 20.0.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/README.md +15 -5
- package/dist/cjs/client/PerpsClient.d.ts +14 -8
- package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
- package/dist/cjs/client/PerpsClient.js +145 -53
- package/dist/cjs/client/PerpsClient.js.map +1 -1
- package/dist/cjs/client/createPerpsClient.d.ts +1 -6
- package/dist/cjs/client/createPerpsClient.d.ts.map +1 -1
- package/dist/cjs/client/createPerpsClient.js +1 -14
- package/dist/cjs/client/createPerpsClient.js.map +1 -1
- package/dist/cjs/index.d.ts +6 -4
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +11 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/services/getOhlcv.d.ts.map +1 -1
- package/dist/cjs/services/getOhlcv.js.map +1 -1
- package/dist/cjs/types/api.d.ts +7 -6
- package/dist/cjs/types/api.d.ts.map +1 -1
- package/dist/cjs/types/config.d.ts +0 -9
- package/dist/cjs/types/config.d.ts.map +1 -1
- package/dist/cjs/types/provider.d.ts +5 -6
- package/dist/cjs/types/provider.d.ts.map +1 -1
- package/dist/cjs/types/withdrawal.d.ts +4 -2
- package/dist/cjs/types/withdrawal.d.ts.map +1 -1
- package/dist/cjs/utils/calculations.d.ts.map +1 -1
- package/dist/cjs/utils/calculations.js +107 -38
- package/dist/cjs/utils/calculations.js.map +1 -1
- package/dist/cjs/utils/decimal.d.ts +4 -0
- package/dist/cjs/utils/decimal.d.ts.map +1 -0
- package/dist/cjs/utils/decimal.js +14 -0
- package/dist/cjs/utils/decimal.js.map +1 -0
- package/dist/cjs/utils/math.d.ts +4 -0
- package/dist/cjs/utils/math.d.ts.map +1 -0
- package/dist/cjs/utils/math.js +8 -0
- package/dist/cjs/utils/math.js.map +1 -0
- package/dist/cjs/utils/parse.d.ts +1 -0
- package/dist/cjs/utils/parse.d.ts.map +1 -1
- package/dist/cjs/utils/parse.js +15 -0
- package/dist/cjs/utils/parse.js.map +1 -1
- package/dist/cjs/utils/positionMath.d.ts +5 -0
- package/dist/cjs/utils/positionMath.d.ts.map +1 -1
- package/dist/cjs/utils/positionMath.js +53 -6
- package/dist/cjs/utils/positionMath.js.map +1 -1
- package/dist/cjs/utils/setupActions.d.ts +4 -2
- package/dist/cjs/utils/setupActions.d.ts.map +1 -1
- package/dist/cjs/utils/setupActions.js +9 -1
- package/dist/cjs/utils/setupActions.js.map +1 -1
- package/dist/cjs/utils/switchChain.js +1 -1
- package/dist/cjs/utils/switchChain.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/websocket/PerpsWsClient.d.ts +0 -1
- package/dist/cjs/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/cjs/websocket/PerpsWsClient.js +0 -7
- package/dist/cjs/websocket/PerpsWsClient.js.map +1 -1
- package/dist/esm/client/PerpsClient.d.ts +70 -61
- package/dist/esm/client/PerpsClient.d.ts.map +1 -1
- package/dist/esm/client/PerpsClient.js +215 -107
- package/dist/esm/client/PerpsClient.js.map +1 -1
- package/dist/esm/client/createPerpsClient.d.ts +1 -12
- package/dist/esm/client/createPerpsClient.d.ts.map +1 -1
- package/dist/esm/client/createPerpsClient.js +1 -19
- package/dist/esm/client/createPerpsClient.js.map +1 -1
- package/dist/esm/client/requireProvider.d.ts +1 -1
- package/dist/esm/client/requireProvider.js +1 -1
- package/dist/esm/index.d.ts +6 -4
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +5 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/services/getOhlcv.d.ts +1 -0
- package/dist/esm/services/getOhlcv.d.ts.map +1 -1
- package/dist/esm/services/getOhlcv.js.map +1 -1
- package/dist/esm/types/api.d.ts +39 -36
- package/dist/esm/types/api.d.ts.map +1 -1
- package/dist/esm/types/config.d.ts +0 -27
- package/dist/esm/types/config.d.ts.map +1 -1
- package/dist/esm/types/provider.d.ts +28 -33
- package/dist/esm/types/provider.d.ts.map +1 -1
- package/dist/esm/types/withdrawal.d.ts +24 -15
- package/dist/esm/types/withdrawal.d.ts.map +1 -1
- package/dist/esm/utils/calculations.d.ts +3 -2
- package/dist/esm/utils/calculations.d.ts.map +1 -1
- package/dist/esm/utils/calculations.js +109 -39
- package/dist/esm/utils/calculations.js.map +1 -1
- package/dist/esm/utils/decimal.d.ts +9 -0
- package/dist/esm/utils/decimal.d.ts.map +1 -0
- package/dist/esm/utils/decimal.js +12 -0
- package/dist/esm/utils/decimal.js.map +1 -0
- package/dist/esm/utils/math.d.ts +6 -0
- package/dist/esm/utils/math.d.ts.map +1 -0
- package/dist/esm/utils/math.js +5 -0
- package/dist/esm/utils/math.js.map +1 -0
- package/dist/esm/utils/parse.d.ts +7 -0
- package/dist/esm/utils/parse.d.ts.map +1 -1
- package/dist/esm/utils/parse.js +20 -0
- package/dist/esm/utils/parse.js.map +1 -1
- package/dist/esm/utils/positionMath.d.ts +13 -0
- package/dist/esm/utils/positionMath.d.ts.map +1 -1
- package/dist/esm/utils/positionMath.js +60 -6
- package/dist/esm/utils/positionMath.js.map +1 -1
- package/dist/esm/utils/setupActions.d.ts +17 -8
- package/dist/esm/utils/setupActions.d.ts.map +1 -1
- package/dist/esm/utils/setupActions.js +20 -7
- package/dist/esm/utils/setupActions.js.map +1 -1
- package/dist/esm/utils/switchChain.js +1 -1
- package/dist/esm/utils/switchChain.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/websocket/PerpsWsClient.d.ts +0 -7
- package/dist/esm/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/esm/websocket/PerpsWsClient.js +0 -7
- package/dist/esm/websocket/PerpsWsClient.js.map +1 -1
- package/dist/types/client/PerpsClient.d.ts +70 -61
- package/dist/types/client/PerpsClient.d.ts.map +1 -1
- package/dist/types/client/createPerpsClient.d.ts +1 -12
- package/dist/types/client/createPerpsClient.d.ts.map +1 -1
- package/dist/types/client/requireProvider.d.ts +1 -1
- package/dist/types/index.d.ts +6 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/services/getOhlcv.d.ts +1 -0
- package/dist/types/services/getOhlcv.d.ts.map +1 -1
- package/dist/types/types/api.d.ts +39 -36
- package/dist/types/types/api.d.ts.map +1 -1
- package/dist/types/types/config.d.ts +0 -27
- package/dist/types/types/config.d.ts.map +1 -1
- package/dist/types/types/provider.d.ts +28 -33
- package/dist/types/types/provider.d.ts.map +1 -1
- package/dist/types/types/withdrawal.d.ts +24 -15
- package/dist/types/types/withdrawal.d.ts.map +1 -1
- package/dist/types/utils/calculations.d.ts +3 -2
- package/dist/types/utils/calculations.d.ts.map +1 -1
- package/dist/types/utils/decimal.d.ts +9 -0
- package/dist/types/utils/decimal.d.ts.map +1 -0
- package/dist/types/utils/math.d.ts +6 -0
- package/dist/types/utils/math.d.ts.map +1 -0
- package/dist/types/utils/parse.d.ts +7 -0
- package/dist/types/utils/parse.d.ts.map +1 -1
- package/dist/types/utils/positionMath.d.ts +13 -0
- package/dist/types/utils/positionMath.d.ts.map +1 -1
- package/dist/types/utils/setupActions.d.ts +17 -8
- package/dist/types/utils/setupActions.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/websocket/PerpsWsClient.d.ts +0 -7
- package/dist/types/websocket/PerpsWsClient.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client/PerpsClient.ts +296 -137
- package/src/client/createPerpsClient.ts +4 -32
- package/src/client/requireProvider.ts +1 -1
- package/src/index.ts +8 -5
- package/src/services/getOhlcv.ts +1 -0
- package/src/types/api.ts +40 -40
- package/src/types/config.ts +0 -30
- package/src/types/provider.ts +29 -36
- package/src/types/withdrawal.ts +24 -15
- package/src/utils/calculations.ts +114 -43
- package/src/utils/decimal.ts +13 -0
- package/src/utils/math.ts +7 -0
- package/src/utils/parse.ts +25 -0
- package/src/utils/positionMath.ts +66 -6
- package/src/utils/setupActions.ts +27 -13
- package/src/utils/switchChain.ts +1 -1
- package/src/version.ts +1 -1
- package/src/websocket/PerpsWsClient.ts +0 -19
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
AccountConfigSetting,
|
|
2
3
|
AccountResponse,
|
|
3
4
|
AccountSummary,
|
|
4
5
|
ActionParamsMap,
|
|
@@ -16,9 +17,12 @@ import type {
|
|
|
16
17
|
Position,
|
|
17
18
|
Provider,
|
|
18
19
|
ProviderAction,
|
|
20
|
+
SetupAction,
|
|
21
|
+
SetupOption,
|
|
19
22
|
SignedActionStep,
|
|
20
23
|
} from '@lifi/perps-types'
|
|
21
24
|
import {
|
|
25
|
+
ActionRelay,
|
|
22
26
|
ActionType,
|
|
23
27
|
META_PROVIDER,
|
|
24
28
|
PerpsErrorCode,
|
|
@@ -63,6 +67,7 @@ import type {
|
|
|
63
67
|
PlaceTwapOrderParams,
|
|
64
68
|
ProviderSetup,
|
|
65
69
|
SendAssetActionParams,
|
|
70
|
+
SetupChecklistItem,
|
|
66
71
|
SubmitOnboardingParams,
|
|
67
72
|
WithdrawParams,
|
|
68
73
|
} from '../types/api.js'
|
|
@@ -80,6 +85,7 @@ import type {
|
|
|
80
85
|
SignActionsContext,
|
|
81
86
|
} from '../types/provider.js'
|
|
82
87
|
import type { WithdrawableBalance, WithdrawFlow } from '../types/withdrawal.js'
|
|
88
|
+
import { isUserFacingSetupStep } from '../utils/setupActions.js'
|
|
83
89
|
import { signTypedDataWithSigner } from '../utils/signTypedData.js'
|
|
84
90
|
import {
|
|
85
91
|
eip712DomainChainId,
|
|
@@ -89,6 +95,127 @@ import {
|
|
|
89
95
|
import { createPerpsClient } from './createPerpsClient.js'
|
|
90
96
|
import { requireProvider as resolveProvider } from './requireProvider.js'
|
|
91
97
|
|
|
98
|
+
/** Absent `sequence` sorts last, so an unordered step gates nothing. */
|
|
99
|
+
function sequenceOf(descriptor: ProviderAction): number {
|
|
100
|
+
return descriptor.sequence ?? Number.MAX_SAFE_INTEGER
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const SIGNERS: ReadonlySet<string> = new Set(Object.values(PerpsSigner))
|
|
104
|
+
const RELAYS: ReadonlySet<string> = new Set(Object.values(ActionRelay))
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Reject provider metadata whose steps the SDK cannot classify. A step with no
|
|
108
|
+
* known `signer`, `relay`, `options` or `revoke` would otherwise read as
|
|
109
|
+
* satisfied and report a not-onboarded account as ready.
|
|
110
|
+
*/
|
|
111
|
+
function assertSetupContract(metadata: Provider): void {
|
|
112
|
+
const reject = (step: ActionType, problem: string): never => {
|
|
113
|
+
throw new PerpsError(
|
|
114
|
+
PerpsErrorCode.SDKError,
|
|
115
|
+
`Provider '${metadata.key}' step '${step}' ${problem}; this SDK needs a ` +
|
|
116
|
+
`backend that emits signer, relay, options and revoke.`
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
for (const descriptor of [...metadata.setup, ...metadata.actions]) {
|
|
120
|
+
if (!SIGNERS.has(descriptor.signer)) {
|
|
121
|
+
reject(descriptor.type, 'declares no known signer')
|
|
122
|
+
}
|
|
123
|
+
if (!RELAYS.has(descriptor.relay)) {
|
|
124
|
+
reject(descriptor.type, 'declares no known relay')
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const actionTypes = new Set(metadata.actions.map((d) => d.type))
|
|
128
|
+
for (const descriptor of metadata.setup) {
|
|
129
|
+
if (descriptor.options === undefined) {
|
|
130
|
+
reject(descriptor.type, 'declares no options')
|
|
131
|
+
}
|
|
132
|
+
if (descriptor.options !== null && descriptor.options.length === 0) {
|
|
133
|
+
reject(descriptor.type, 'declares an empty options list')
|
|
134
|
+
}
|
|
135
|
+
if (descriptor.revoke === undefined) {
|
|
136
|
+
reject(descriptor.type, 'declares no revoke')
|
|
137
|
+
}
|
|
138
|
+
if (descriptor.revoke !== null && !actionTypes.has(descriptor.revoke)) {
|
|
139
|
+
reject(
|
|
140
|
+
descriptor.type,
|
|
141
|
+
`revokes with '${descriptor.revoke}', which Provider.actions does not declare`
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
const defaults = (descriptor.options ?? []).filter(
|
|
145
|
+
(option) => option.default === true
|
|
146
|
+
)
|
|
147
|
+
if (defaults.length > 1) {
|
|
148
|
+
reject(descriptor.type, 'marks more than one option default')
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Only a USER-signed non-choice step is staged for the user to sign. */
|
|
154
|
+
function isStageable(descriptor: SetupAction): boolean {
|
|
155
|
+
return descriptor.options === null && descriptor.signer === PerpsSigner.USER
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function satisfiedTypes(settings: AccountConfigSetting[]): Set<ActionType> {
|
|
159
|
+
return new Set(
|
|
160
|
+
settings.filter((setting) => setting.satisfied).map((s) => s.type)
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** The choice option whose every bound param equals the projected value. */
|
|
165
|
+
function selectedOption(
|
|
166
|
+
descriptor: SetupAction,
|
|
167
|
+
settings: AccountConfigSetting[]
|
|
168
|
+
): SetupOption | null {
|
|
169
|
+
if (descriptor.options === null) {
|
|
170
|
+
return null
|
|
171
|
+
}
|
|
172
|
+
const values =
|
|
173
|
+
settings.find((setting) => setting.type === descriptor.type)?.values ?? []
|
|
174
|
+
return (
|
|
175
|
+
descriptor.options.find((option) => {
|
|
176
|
+
const bound = Object.entries(option.params)
|
|
177
|
+
return (
|
|
178
|
+
bound.length > 0 &&
|
|
179
|
+
bound.every(([name, value]) =>
|
|
180
|
+
values.some((v) => v.name === name && v.value === value)
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
}) ?? null
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The projected value of the param a choice's options bind, as the venue
|
|
189
|
+
* names it, whether or not an option binds that value.
|
|
190
|
+
*/
|
|
191
|
+
function currentChoiceValue(
|
|
192
|
+
descriptor: SetupAction,
|
|
193
|
+
settings: AccountConfigSetting[]
|
|
194
|
+
): string | null {
|
|
195
|
+
if (descriptor.options === null) {
|
|
196
|
+
return null
|
|
197
|
+
}
|
|
198
|
+
const names = new Set(
|
|
199
|
+
descriptor.options.flatMap((option) => Object.keys(option.params))
|
|
200
|
+
)
|
|
201
|
+
const value =
|
|
202
|
+
settings
|
|
203
|
+
.find((setting) => setting.type === descriptor.type)
|
|
204
|
+
?.values.find((v) => names.has(v.name))?.value ?? null
|
|
205
|
+
return value === null ? null : String(value)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Throw the first per-action failure a 200 OK `/executeAction` carried. */
|
|
209
|
+
function assertAllSucceeded(results: ActionResult[]): void {
|
|
210
|
+
const failure = results.find((r) => !r.success)
|
|
211
|
+
if (failure) {
|
|
212
|
+
throw new PerpsError(
|
|
213
|
+
failure.errorCode ?? PerpsErrorCode.ExchangeRejected,
|
|
214
|
+
failure.error
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
92
219
|
function isNonNegativeDecimal(value: string): boolean {
|
|
93
220
|
try {
|
|
94
221
|
return new Big(value).gte(0)
|
|
@@ -105,11 +232,9 @@ function findActionDescriptor(
|
|
|
105
232
|
metadata: Provider,
|
|
106
233
|
action: ActionType
|
|
107
234
|
): ProviderAction {
|
|
108
|
-
const descriptor = [
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
...metadata.actions,
|
|
112
|
-
].find((d) => d.type === action)
|
|
235
|
+
const descriptor = [...metadata.setup, ...metadata.actions].find(
|
|
236
|
+
(d) => d.type === action
|
|
237
|
+
)
|
|
113
238
|
if (!descriptor) {
|
|
114
239
|
throw new PerpsError(
|
|
115
240
|
PerpsErrorCode.SDKError,
|
|
@@ -171,7 +296,7 @@ export class PerpsClient {
|
|
|
171
296
|
|
|
172
297
|
/**
|
|
173
298
|
* Set or update the end-user's wallet. Used whenever an action's descriptor
|
|
174
|
-
* names
|
|
299
|
+
* names `PerpsSigner.USER` as its `signer`. Pass undefined to clear.
|
|
175
300
|
*
|
|
176
301
|
* @public
|
|
177
302
|
*/
|
|
@@ -205,17 +330,15 @@ export class PerpsClient {
|
|
|
205
330
|
}
|
|
206
331
|
|
|
207
332
|
private async getProviderMetadata(provider: string): Promise<Provider> {
|
|
208
|
-
|
|
209
|
-
if (
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
this.providerMetadataCache.set(d.key, d)
|
|
333
|
+
let metadata = this.providerMetadataCache.get(provider)
|
|
334
|
+
if (!metadata) {
|
|
335
|
+
const { providers } = await getProviders(this.sdkClient)
|
|
336
|
+
for (const d of providers) {
|
|
337
|
+
this.providerMetadataCache.set(d.key, d)
|
|
338
|
+
}
|
|
339
|
+
metadata = this.providerMetadataCache.get(provider)
|
|
216
340
|
}
|
|
217
341
|
|
|
218
|
-
const metadata = this.providerMetadataCache.get(provider)
|
|
219
342
|
if (!metadata) {
|
|
220
343
|
const error = new PerpsError(
|
|
221
344
|
PerpsErrorCode.SDKError,
|
|
@@ -224,6 +347,7 @@ export class PerpsClient {
|
|
|
224
347
|
error.tool = '@lifi/perps-sdk'
|
|
225
348
|
throw error
|
|
226
349
|
}
|
|
350
|
+
assertSetupContract(metadata)
|
|
227
351
|
return metadata
|
|
228
352
|
}
|
|
229
353
|
|
|
@@ -256,7 +380,7 @@ export class PerpsClient {
|
|
|
256
380
|
* Ask the provider plugin for the signer-bearing wire fields of `action` —
|
|
257
381
|
* the on-wire `signerAddress` and any signer-derived params (e.g.
|
|
258
382
|
* Hyperliquid's `agentAddress` for `APPROVE_AGENT`). Forwards the descriptor's
|
|
259
|
-
* `
|
|
383
|
+
* `signer` so the plugin can branch on signer role. Returns empty when the
|
|
260
384
|
* plugin signs as the user or with a non-EVM credential. Core constructs no
|
|
261
385
|
* `signerAddress` itself; signer identity is plugin-owned.
|
|
262
386
|
*/
|
|
@@ -272,17 +396,17 @@ export class PerpsClient {
|
|
|
272
396
|
return plugin.resolveActionRequest(
|
|
273
397
|
descriptor.type,
|
|
274
398
|
address,
|
|
275
|
-
descriptor.
|
|
399
|
+
descriptor.signer
|
|
276
400
|
)
|
|
277
401
|
}
|
|
278
402
|
|
|
279
403
|
/**
|
|
280
404
|
* Delegate signing of `actions` to the provider plugin, one call per
|
|
281
405
|
* consecutive run of steps sharing a descriptor. Each call carries that
|
|
282
|
-
* descriptor's `signingMethod` and `
|
|
406
|
+
* descriptor's `signingMethod` and `signer`, so a mixed batch signs every
|
|
283
407
|
* step with the signer its own descriptor declares; the signed steps come
|
|
284
408
|
* back in the batch's original order. The plugin owns every signing arm and
|
|
285
|
-
* branches on `
|
|
409
|
+
* branches on `signer` internally, reading the end-user's wallet from the
|
|
286
410
|
* {@link SignActionsContext} when an arm signs as the user.
|
|
287
411
|
*
|
|
288
412
|
* @throws {PerpsError} When a step's action is not declared by the provider,
|
|
@@ -405,9 +529,9 @@ export class PerpsClient {
|
|
|
405
529
|
|
|
406
530
|
/**
|
|
407
531
|
* Assemble the per-call context the provider plugin needs in order to sign:
|
|
408
|
-
* the end-user's wallet and the descriptor's declared `
|
|
409
|
-
* forwards `
|
|
410
|
-
* branch on
|
|
532
|
+
* the end-user's wallet and the descriptor's declared `signer`. Core
|
|
533
|
+
* forwards `signer` as data so the plugin can pick WHO signs; it does not
|
|
534
|
+
* branch on it. Provider-owned session credentials (the Hyperliquid agent
|
|
411
535
|
* keypair, Lighter's API key) are resolved inside the provider's
|
|
412
536
|
* `signActions`, not threaded through here.
|
|
413
537
|
*
|
|
@@ -425,7 +549,7 @@ export class PerpsClient {
|
|
|
425
549
|
userWallet?: PerpsClientSigner,
|
|
426
550
|
onProgress?: (progress: SignActionProgress) => void
|
|
427
551
|
): SignActionsContext {
|
|
428
|
-
const ctx: SignActionsContext = {
|
|
552
|
+
const ctx: SignActionsContext = { signer: descriptor.signer }
|
|
429
553
|
if (onProgress !== undefined) {
|
|
430
554
|
ctx.onProgress = onProgress
|
|
431
555
|
}
|
|
@@ -501,7 +625,7 @@ export class PerpsClient {
|
|
|
501
625
|
/**
|
|
502
626
|
* Fetch the user's account state from the backend and attach the
|
|
503
627
|
* SDK-projected `settings` array — one `AccountConfigSetting` per
|
|
504
|
-
* descriptor on `Provider.setup
|
|
628
|
+
* descriptor on `Provider.setup`. Callers read
|
|
505
629
|
* `result.settings` directly without re-deriving values from the typed
|
|
506
630
|
* `AccountConfig`.
|
|
507
631
|
*
|
|
@@ -518,30 +642,27 @@ export class PerpsClient {
|
|
|
518
642
|
fetchAccount(this.sdkClient, params),
|
|
519
643
|
this.getProviderMetadata(params.provider),
|
|
520
644
|
])
|
|
521
|
-
const settings = plugin.projectConfig(
|
|
522
|
-
response.config,
|
|
523
|
-
metadata.setup,
|
|
524
|
-
metadata.options
|
|
525
|
-
)
|
|
645
|
+
const settings = plugin.projectConfig(response.config, metadata.setup)
|
|
526
646
|
return { ...response, settings }
|
|
527
647
|
}
|
|
528
648
|
|
|
529
649
|
/**
|
|
530
|
-
* The user's current venue-side settings for a market — the margin
|
|
531
|
-
* and leverage the next order on it will use. Resolves
|
|
532
|
-
*
|
|
533
|
-
* has no such read at all).
|
|
650
|
+
* The user's current venue-side settings for a perps market — the margin
|
|
651
|
+
* mode and leverage the next order on it will use. Resolves the venue value
|
|
652
|
+
* or throws.
|
|
534
653
|
*
|
|
535
|
-
* @throws {PerpsError} When the provider plugin is not registered
|
|
654
|
+
* @throws {PerpsError} When the provider plugin is not registered,
|
|
655
|
+
* `ValidationError` for a spot market, or any other `PerpsError` when the
|
|
656
|
+
* venue read fails or carries no usable value.
|
|
536
657
|
* @public
|
|
537
658
|
*/
|
|
538
659
|
async getMarketSettings(params: {
|
|
539
660
|
provider: string
|
|
540
661
|
address: Address
|
|
541
662
|
market: MarketRef
|
|
542
|
-
}): Promise<MarketSettings
|
|
663
|
+
}): Promise<MarketSettings> {
|
|
543
664
|
const plugin = this.requireProvider(params.provider)
|
|
544
|
-
return plugin.getMarketSettings
|
|
665
|
+
return plugin.getMarketSettings({
|
|
545
666
|
address: params.address,
|
|
546
667
|
market: params.market,
|
|
547
668
|
})
|
|
@@ -690,7 +811,7 @@ export class PerpsClient {
|
|
|
690
811
|
* @returns `undefined` when the registered plugin declares no withdrawable
|
|
691
812
|
* read.
|
|
692
813
|
* @throws {PerpsError} When the provider plugin is not registered, when
|
|
693
|
-
* either the plugin read or the asset sync fails,
|
|
814
|
+
* either the plugin read or the asset sync fails, when a row's
|
|
694
815
|
* `withdrawalFee` is not a non-negative decimal.
|
|
695
816
|
* @public
|
|
696
817
|
*/
|
|
@@ -742,6 +863,9 @@ export class PerpsClient {
|
|
|
742
863
|
route: row.route,
|
|
743
864
|
available: row.available,
|
|
744
865
|
withdrawalFee: row.withdrawalFee,
|
|
866
|
+
...(row.isFeeDeducted === undefined
|
|
867
|
+
? {}
|
|
868
|
+
: { isFeeDeducted: row.isFeeDeducted }),
|
|
745
869
|
},
|
|
746
870
|
]
|
|
747
871
|
})
|
|
@@ -773,15 +897,17 @@ export class PerpsClient {
|
|
|
773
897
|
}
|
|
774
898
|
|
|
775
899
|
/**
|
|
776
|
-
* Return the
|
|
777
|
-
*
|
|
778
|
-
* `checklist` carries the renderable onboarding list: every
|
|
779
|
-
*
|
|
780
|
-
* omitted.
|
|
900
|
+
* Return the setup steps this account must still sign as a flat,
|
|
901
|
+
* self-describing list. Trading is gated on `isReady === true`.
|
|
902
|
+
* `checklist` carries the renderable onboarding list: every choice step and
|
|
903
|
+
* every `USER`-signed step with its satisfied state, with not-required
|
|
904
|
+
* conditional steps omitted.
|
|
781
905
|
*
|
|
782
|
-
* `
|
|
783
|
-
*
|
|
784
|
-
*
|
|
906
|
+
* A non-choice `SDK`-signed step is NEVER returned here — the SDK drains it
|
|
907
|
+
* with the provider's own credentials. A choice is listed but never staged
|
|
908
|
+
* or executed, whatever its `signer`: the user picks an option through
|
|
909
|
+
* {@link executeProviderOption}, and `isReady` stays `false` until every
|
|
910
|
+
* choice on `checklist` is satisfied.
|
|
785
911
|
*
|
|
786
912
|
* @public
|
|
787
913
|
*/
|
|
@@ -807,19 +933,15 @@ export class PerpsClient {
|
|
|
807
933
|
}
|
|
808
934
|
}
|
|
809
935
|
|
|
810
|
-
const
|
|
936
|
+
const settings = await this.resolveSetupSettings(provider, address)
|
|
937
|
+
const satisfiedSetup = satisfiedTypes(settings)
|
|
811
938
|
const pendingSetup = metadata.setup.filter(
|
|
812
939
|
(descriptor) => !satisfiedSetup.has(descriptor.type)
|
|
813
940
|
)
|
|
814
941
|
|
|
815
942
|
const plugin = this.sdkClient.getProvider(provider)
|
|
816
|
-
|
|
817
|
-
const
|
|
818
|
-
internalTypes.has(descriptor.type) &&
|
|
819
|
-
!descriptor.signers.includes(PerpsSigner.USER)
|
|
820
|
-
const visibleSetup = pendingSetup.filter(
|
|
821
|
-
(descriptor) => !isInternal(descriptor)
|
|
822
|
-
)
|
|
943
|
+
|
|
944
|
+
const stageable = pendingSetup.filter(isStageable)
|
|
823
945
|
|
|
824
946
|
// The backend filters already-satisfied setup actions and returns typed
|
|
825
947
|
// data for those still outstanding; each plugin contributes its own
|
|
@@ -827,7 +949,7 @@ export class PerpsClient {
|
|
|
827
949
|
const actions = await this.buildProviderSetupActions(
|
|
828
950
|
provider,
|
|
829
951
|
address,
|
|
830
|
-
|
|
952
|
+
stageable
|
|
831
953
|
)
|
|
832
954
|
|
|
833
955
|
// A staged step is one the build produced actions for — a pending
|
|
@@ -835,69 +957,64 @@ export class PerpsClient {
|
|
|
835
957
|
// (backend-gated) or not applicable to this account.
|
|
836
958
|
const stagedTypes = new Set(actions.map((step) => step.action))
|
|
837
959
|
const conditionalTypes = new Set(plugin?.conditionalSetupActions ?? [])
|
|
838
|
-
const sequenceOf = (descriptor: ProviderAction): number =>
|
|
839
|
-
descriptor.sequence ?? Number.MAX_SAFE_INTEGER
|
|
840
960
|
const checklist = metadata.setup
|
|
841
|
-
.filter(
|
|
961
|
+
.filter(isUserFacingSetupStep)
|
|
842
962
|
.filter(
|
|
843
963
|
(descriptor) =>
|
|
964
|
+
descriptor.options !== null ||
|
|
844
965
|
!conditionalTypes.has(descriptor.type) ||
|
|
845
966
|
stagedTypes.has(descriptor.type)
|
|
846
967
|
)
|
|
847
968
|
.sort((a, b) => sequenceOf(a) - sequenceOf(b))
|
|
848
969
|
.map((descriptor) => ({
|
|
849
970
|
descriptor,
|
|
850
|
-
satisfied:
|
|
971
|
+
satisfied:
|
|
972
|
+
descriptor.options !== null
|
|
973
|
+
? satisfiedSetup.has(descriptor.type)
|
|
974
|
+
: !stagedTypes.has(descriptor.type),
|
|
975
|
+
selected: selectedOption(descriptor, settings),
|
|
976
|
+
currentValue: currentChoiceValue(descriptor, settings),
|
|
851
977
|
}))
|
|
852
978
|
|
|
853
|
-
await this.
|
|
979
|
+
await this.drainSetup(
|
|
854
980
|
provider,
|
|
855
981
|
address,
|
|
856
|
-
pendingSetup.filter(
|
|
857
|
-
|
|
982
|
+
pendingSetup.filter(
|
|
983
|
+
(descriptor) =>
|
|
984
|
+
descriptor.options === null && descriptor.signer === PerpsSigner.SDK
|
|
985
|
+
),
|
|
986
|
+
stageable.filter((descriptor) => stagedTypes.has(descriptor.type))
|
|
858
987
|
)
|
|
859
988
|
|
|
860
989
|
return {
|
|
861
990
|
accountExists: true,
|
|
862
991
|
setup: actions,
|
|
863
|
-
isReady:
|
|
992
|
+
isReady:
|
|
993
|
+
actions.length === 0 && checklist.every((item) => item.satisfied),
|
|
864
994
|
checklist,
|
|
865
995
|
}
|
|
866
996
|
}
|
|
867
997
|
|
|
868
998
|
/**
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
*
|
|
999
|
+
* Project the provider's own typed account config onto its setup steps. This
|
|
1000
|
+
* catches client-held auth state (e.g. Ondo SIWE/JWT) that the backend
|
|
1001
|
+
* cannot observe, and carries the current value of each choice.
|
|
872
1002
|
*/
|
|
873
|
-
private async
|
|
1003
|
+
private async resolveSetupSettings(
|
|
874
1004
|
provider: string,
|
|
875
1005
|
address: Address
|
|
876
|
-
): Promise<
|
|
1006
|
+
): Promise<AccountConfigSetting[]> {
|
|
877
1007
|
const metadata = await this.getProviderMetadata(provider)
|
|
878
1008
|
const plugin = this.sdkClient.getProvider(provider)
|
|
879
1009
|
if (!plugin || typeof plugin.getAccount !== 'function') {
|
|
880
|
-
return
|
|
1010
|
+
return []
|
|
881
1011
|
}
|
|
882
1012
|
const account = await plugin.getAccount({ address })
|
|
883
|
-
|
|
884
|
-
account.config,
|
|
885
|
-
metadata.setup,
|
|
886
|
-
metadata.options
|
|
887
|
-
)
|
|
888
|
-
const setupTypes = new Set(
|
|
889
|
-
metadata.setup.map((descriptor) => descriptor.type)
|
|
890
|
-
)
|
|
891
|
-
return new Set(
|
|
892
|
-
settings
|
|
893
|
-
.filter((setting) => setting.satisfied && setupTypes.has(setting.type))
|
|
894
|
-
.map((setting) => setting.type)
|
|
895
|
-
)
|
|
1013
|
+
return plugin.projectConfig(account.config, metadata.setup)
|
|
896
1014
|
}
|
|
897
1015
|
|
|
898
1016
|
/**
|
|
899
|
-
* Drain the pending
|
|
900
|
-
* `PerpsProviderPlugin.internalSetupActions`. Each step is built, signed,
|
|
1017
|
+
* Drain the pending `SDK`-signed non-choice steps: each is built, signed,
|
|
901
1018
|
* and executed in place with the provider's own credentials. A step is
|
|
902
1019
|
* deferred while any staged user-facing step with a lower `sequence` is
|
|
903
1020
|
* outstanding — it cannot succeed before its prerequisite (e.g. SET_REFERRAL
|
|
@@ -906,17 +1023,15 @@ export class PerpsClient {
|
|
|
906
1023
|
* blocks setup — the step stays unsatisfied and is retried on a later
|
|
907
1024
|
* `checkSetup`.
|
|
908
1025
|
*/
|
|
909
|
-
private async
|
|
1026
|
+
private async drainSetup(
|
|
910
1027
|
provider: string,
|
|
911
1028
|
address: Address,
|
|
912
|
-
|
|
913
|
-
stagedVisible:
|
|
1029
|
+
drainable: SetupAction[],
|
|
1030
|
+
stagedVisible: SetupAction[]
|
|
914
1031
|
): Promise<void> {
|
|
915
|
-
const
|
|
916
|
-
descriptor.sequence ?? Number.MAX_SAFE_INTEGER
|
|
917
|
-
for (const descriptor of internalPending) {
|
|
1032
|
+
for (const descriptor of drainable) {
|
|
918
1033
|
// A tie (equal sequences, or both absent) declares no order, so the
|
|
919
|
-
//
|
|
1034
|
+
// drained step defers to the next checkSetup rather than racing.
|
|
920
1035
|
const blocked = stagedVisible.some(
|
|
921
1036
|
(staged) => sequenceOf(staged) <= sequenceOf(descriptor)
|
|
922
1037
|
)
|
|
@@ -944,7 +1059,7 @@ export class PerpsClient {
|
|
|
944
1059
|
}
|
|
945
1060
|
} catch (error) {
|
|
946
1061
|
console.debug(
|
|
947
|
-
`[perps-sdk]
|
|
1062
|
+
`[perps-sdk] setup step '${descriptor.type}' for '${provider}' did not drain; will retry on the next checkSetup.`,
|
|
948
1063
|
error
|
|
949
1064
|
)
|
|
950
1065
|
}
|
|
@@ -958,7 +1073,7 @@ export class PerpsClient {
|
|
|
958
1073
|
private async buildProviderSetupActions(
|
|
959
1074
|
provider: string,
|
|
960
1075
|
address: Address,
|
|
961
|
-
descriptors:
|
|
1076
|
+
descriptors: SetupAction[]
|
|
962
1077
|
): Promise<ActionStep[]> {
|
|
963
1078
|
const setupPriority = (descriptor: ProviderAction): number =>
|
|
964
1079
|
descriptor.signingMethod === SigningMethod.SIWE ? 0 : 1
|
|
@@ -996,9 +1111,11 @@ export class PerpsClient {
|
|
|
996
1111
|
|
|
997
1112
|
/**
|
|
998
1113
|
* Build the unsigned setup `ActionStep`s still outstanding for an account,
|
|
999
|
-
* ordered by descriptor `sequence`.
|
|
1000
|
-
*
|
|
1001
|
-
*
|
|
1114
|
+
* ordered by descriptor `sequence`. Only a `USER`-signed non-choice step is
|
|
1115
|
+
* staged: an `SDK`-signed non-choice step drains inside {@link checkSetup}
|
|
1116
|
+
* and a choice executes the option the user picks. The backend filters
|
|
1117
|
+
* already-satisfied setup; each plugin contributes its own signer-bearing
|
|
1118
|
+
* request fields and any local-state params (e.g. Lighter's known pubkey).
|
|
1002
1119
|
*
|
|
1003
1120
|
* @public
|
|
1004
1121
|
*/
|
|
@@ -1011,7 +1128,7 @@ export class PerpsClient {
|
|
|
1011
1128
|
const actions = await this.buildProviderSetupActions(
|
|
1012
1129
|
provider,
|
|
1013
1130
|
address,
|
|
1014
|
-
metadata.setup
|
|
1131
|
+
metadata.setup.filter(isStageable)
|
|
1015
1132
|
)
|
|
1016
1133
|
return { actions }
|
|
1017
1134
|
}
|
|
@@ -1054,13 +1171,7 @@ export class PerpsClient {
|
|
|
1054
1171
|
|
|
1055
1172
|
await this.notifyExecuteResults(provider, address, results)
|
|
1056
1173
|
|
|
1057
|
-
|
|
1058
|
-
if (failure) {
|
|
1059
|
-
throw new PerpsError(
|
|
1060
|
-
failure.errorCode ?? PerpsErrorCode.ExchangeRejected,
|
|
1061
|
-
failure.error
|
|
1062
|
-
)
|
|
1063
|
-
}
|
|
1174
|
+
assertAllSucceeded(results)
|
|
1064
1175
|
|
|
1065
1176
|
return { results: { results } }
|
|
1066
1177
|
}
|
|
@@ -1068,25 +1179,23 @@ export class PerpsClient {
|
|
|
1068
1179
|
/**
|
|
1069
1180
|
* Sign and submit one pre-staged setup `ActionStep` end-to-end.
|
|
1070
1181
|
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
1075
|
-
* through submit. If the cached step has gone stale (Lighter's `/nextNonce`
|
|
1076
|
-
* advanced underneath us), `executeProviderSetup` will surface a nonce
|
|
1077
|
-
* conflict that the caller invalidates on, refetches `checkSetup`, and
|
|
1078
|
-
* retries with a fresh step.
|
|
1182
|
+
* `step` and `checklist` must come from the same {@link checkSetup} result.
|
|
1183
|
+
* This preserves the nonce allocated while staging and validates sequence
|
|
1184
|
+
* prerequisites against that same snapshot, without another `createAction`
|
|
1185
|
+
* round-trip.
|
|
1079
1186
|
*
|
|
1080
1187
|
* @throws {PerpsError} When the step's action is not in the provider's
|
|
1081
|
-
* `setup` descriptors
|
|
1188
|
+
* `setup` descriptors, or when a lower-`sequence` step on the same
|
|
1189
|
+
* checklist, a choice included, is still unsatisfied.
|
|
1082
1190
|
* @public
|
|
1083
1191
|
*/
|
|
1084
1192
|
async executeProviderSetupAction(params: {
|
|
1085
1193
|
provider: string
|
|
1086
1194
|
address: Address
|
|
1087
1195
|
step: ActionStep
|
|
1196
|
+
checklist: SetupChecklistItem[]
|
|
1088
1197
|
}): Promise<void> {
|
|
1089
|
-
const { provider, address, step } = params
|
|
1198
|
+
const { provider, address, step, checklist } = params
|
|
1090
1199
|
|
|
1091
1200
|
const metadata = await this.getProviderMetadata(provider)
|
|
1092
1201
|
const descriptor = metadata.setup.find((d) => d.type === step.action)
|
|
@@ -1097,6 +1206,17 @@ export class PerpsClient {
|
|
|
1097
1206
|
)
|
|
1098
1207
|
}
|
|
1099
1208
|
|
|
1209
|
+
const blockingStep = checklist.find(
|
|
1210
|
+
(item) =>
|
|
1211
|
+
!item.satisfied && sequenceOf(item.descriptor) < sequenceOf(descriptor)
|
|
1212
|
+
)
|
|
1213
|
+
if (blockingStep) {
|
|
1214
|
+
throw new PerpsError(
|
|
1215
|
+
PerpsErrorCode.SDKError,
|
|
1216
|
+
`Setup step '${step.action}' for '${provider}' is blocked: '${blockingStep.descriptor.type}' runs first and is not satisfied.`
|
|
1217
|
+
)
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1100
1220
|
const signed = await this.signProviderSetupAction(provider, address, step)
|
|
1101
1221
|
|
|
1102
1222
|
// A client-executed setup action (Lighter SET_REFERRAL) produces no
|
|
@@ -1115,22 +1235,13 @@ export class PerpsClient {
|
|
|
1115
1235
|
}
|
|
1116
1236
|
|
|
1117
1237
|
/**
|
|
1118
|
-
*
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1238
|
+
* Execute one option of a choice setup step (Lighter `ACCOUNT_TYPE`,
|
|
1239
|
+
* Hyperliquid `ACCOUNT_MODE`) end-to-end with its bound `{ type, params }`,
|
|
1240
|
+
* throwing on a venue rejection.
|
|
1121
1241
|
*
|
|
1122
|
-
*
|
|
1123
|
-
* trades, but unlike a trade an option change is a single mandatory action:
|
|
1242
|
+
* The option runs through the same {@link execute} pipeline as a trade, but
|
|
1124
1243
|
* a per-action `success: false` (returned as a 200 OK) means the user's
|
|
1125
|
-
* selection was rejected and must surface, not be silently dropped.
|
|
1126
|
-
* wrapper inspects the result and throws a {@link PerpsError} carrying the
|
|
1127
|
-
* venue `error`, giving options the same throw contract that setup has via
|
|
1128
|
-
* {@link executeProviderSetupAction}. The only structural difference is that
|
|
1129
|
-
* an option carries `params` (the selected value) rather than a pre-staged
|
|
1130
|
-
* step.
|
|
1131
|
-
*
|
|
1132
|
-
* `execute` itself is unchanged — it still returns results without throwing,
|
|
1133
|
-
* which the trade hooks rely on for partial-fill handling.
|
|
1244
|
+
* selection was rejected and must surface, not be silently dropped.
|
|
1134
1245
|
*
|
|
1135
1246
|
* @throws {PerpsError} Carrying the venue error when any returned result has
|
|
1136
1247
|
* `success: false`, under that result's `errorCode` when the backend
|
|
@@ -1139,20 +1250,56 @@ export class PerpsClient {
|
|
|
1139
1250
|
* signer, signing failure).
|
|
1140
1251
|
* @public
|
|
1141
1252
|
*/
|
|
1142
|
-
async executeProviderOption
|
|
1253
|
+
async executeProviderOption(params: {
|
|
1143
1254
|
provider: string
|
|
1144
1255
|
address: Address
|
|
1145
|
-
|
|
1146
|
-
params: ActionParamsMap[T]
|
|
1256
|
+
option: SetupOption
|
|
1147
1257
|
}): Promise<void> {
|
|
1148
|
-
const {
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1258
|
+
const { provider, address, option } = params
|
|
1259
|
+
const { results } = await this.execute({
|
|
1260
|
+
provider,
|
|
1261
|
+
address,
|
|
1262
|
+
action: option.type,
|
|
1263
|
+
params: option.params,
|
|
1264
|
+
})
|
|
1265
|
+
assertAllSucceeded(results)
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
/**
|
|
1269
|
+
* Undo a satisfied setup step by executing its `revoke` action through
|
|
1270
|
+
* create, sign and execute, signed with that action's `Provider.actions`
|
|
1271
|
+
* descriptor. The step stages again on the next {@link checkSetup}.
|
|
1272
|
+
*
|
|
1273
|
+
* @throws {PerpsError} `SDKError` when `step.revoke` is `null` or when
|
|
1274
|
+
* `createAction` stages nothing to revoke; otherwise the errors
|
|
1275
|
+
* {@link executeProviderOption} throws.
|
|
1276
|
+
* @public
|
|
1277
|
+
*/
|
|
1278
|
+
async executeProviderRevoke(params: {
|
|
1279
|
+
provider: string
|
|
1280
|
+
address: Address
|
|
1281
|
+
step: SetupAction
|
|
1282
|
+
}): Promise<void> {
|
|
1283
|
+
const { provider, address, step } = params
|
|
1284
|
+
if (step.revoke === null) {
|
|
1151
1285
|
throw new PerpsError(
|
|
1152
|
-
|
|
1153
|
-
|
|
1286
|
+
PerpsErrorCode.SDKError,
|
|
1287
|
+
`Setup step '${step.type}' for '${provider}' declares no revoke.`
|
|
1154
1288
|
)
|
|
1155
1289
|
}
|
|
1290
|
+
const { staged, results } = await this.runAction({
|
|
1291
|
+
provider,
|
|
1292
|
+
address,
|
|
1293
|
+
action: step.revoke,
|
|
1294
|
+
params: {},
|
|
1295
|
+
})
|
|
1296
|
+
if (staged.length === 0) {
|
|
1297
|
+
throw new PerpsError(
|
|
1298
|
+
PerpsErrorCode.SDKError,
|
|
1299
|
+
`Nothing to revoke for setup step '${step.type}' on '${provider}'.`
|
|
1300
|
+
)
|
|
1301
|
+
}
|
|
1302
|
+
assertAllSucceeded(results)
|
|
1156
1303
|
}
|
|
1157
1304
|
|
|
1158
1305
|
/**
|
|
@@ -1333,6 +1480,18 @@ export class PerpsClient {
|
|
|
1333
1480
|
* deposit); called as each leg is submitted and confirmed. */
|
|
1334
1481
|
onProgress?: (progress: SignActionProgress) => void
|
|
1335
1482
|
}): Promise<ExecuteActionResponse> {
|
|
1483
|
+
const { results } = await this.runAction(params)
|
|
1484
|
+
return { results }
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
/** {@link execute}, also returning the steps `createAction` staged. */
|
|
1488
|
+
private async runAction<T extends ActionType>(params: {
|
|
1489
|
+
provider: string
|
|
1490
|
+
address: Address
|
|
1491
|
+
action: T
|
|
1492
|
+
params: ActionParamsMap[T]
|
|
1493
|
+
onProgress?: (progress: SignActionProgress) => void
|
|
1494
|
+
}): Promise<{ staged: ActionStep[]; results: ActionResult[] }> {
|
|
1336
1495
|
const { provider, address, action, onProgress } = params
|
|
1337
1496
|
const metadata = await this.getProviderMetadata(provider)
|
|
1338
1497
|
const descriptor = findActionDescriptor(metadata, action)
|
|
@@ -1363,7 +1522,7 @@ export class PerpsClient {
|
|
|
1363
1522
|
// token-authenticated venue mutations), leaving no backend-bound step. With
|
|
1364
1523
|
// nothing to submit, skip the `/executeAction` hop.
|
|
1365
1524
|
if (signedActions.length === 0) {
|
|
1366
|
-
return { results: [] }
|
|
1525
|
+
return { staged: actions, results: [] }
|
|
1367
1526
|
}
|
|
1368
1527
|
|
|
1369
1528
|
const response = await executeAction(this.sdkClient, {
|
|
@@ -1380,7 +1539,7 @@ export class PerpsClient {
|
|
|
1380
1539
|
|
|
1381
1540
|
await this.notifyExecuteResults(provider, address, results)
|
|
1382
1541
|
|
|
1383
|
-
return { results }
|
|
1542
|
+
return { staged: actions, results }
|
|
1384
1543
|
}
|
|
1385
1544
|
|
|
1386
1545
|
/**
|