@lifi/perps-sdk-provider-ondo 0.0.0 → 1.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/dist/cjs/OndoProvider.d.ts.map +1 -1
- package/dist/cjs/OndoProvider.js +22 -5
- package/dist/cjs/OndoProvider.js.map +1 -1
- package/dist/cjs/accountConfig.d.ts.map +1 -1
- package/dist/cjs/accountConfig.js +12 -1
- package/dist/cjs/accountConfig.js.map +1 -1
- package/dist/cjs/auth/OndoApiKeyStore.d.ts +13 -0
- package/dist/cjs/auth/OndoApiKeyStore.d.ts.map +1 -0
- package/dist/cjs/auth/OndoApiKeyStore.js +42 -0
- package/dist/cjs/auth/OndoApiKeyStore.js.map +1 -0
- package/dist/cjs/auth/hmac.d.ts +8 -0
- package/dist/cjs/auth/hmac.d.ts.map +1 -0
- package/dist/cjs/auth/hmac.js +14 -0
- package/dist/cjs/auth/hmac.js.map +1 -0
- package/dist/cjs/auth/index.d.ts +3 -1
- package/dist/cjs/auth/index.d.ts.map +1 -1
- package/dist/cjs/auth/index.js +5 -2
- package/dist/cjs/auth/index.js.map +1 -1
- package/dist/cjs/auth/signActions.d.ts +3 -2
- package/dist/cjs/auth/signActions.d.ts.map +1 -1
- package/dist/cjs/auth/signActions.js +66 -47
- package/dist/cjs/auth/signActions.js.map +1 -1
- package/dist/cjs/constants.d.ts +4 -0
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +5 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/types/auth.d.ts +7 -0
- package/dist/cjs/types/auth.d.ts.map +1 -1
- package/dist/cjs/utils/apiClient.d.ts.map +1 -1
- package/dist/cjs/utils/apiClient.js.map +1 -1
- package/dist/esm/OndoProvider.d.ts.map +1 -1
- package/dist/esm/OndoProvider.js +26 -6
- package/dist/esm/OndoProvider.js.map +1 -1
- package/dist/esm/accountConfig.d.ts.map +1 -1
- package/dist/esm/accountConfig.js +16 -3
- package/dist/esm/accountConfig.js.map +1 -1
- package/dist/esm/auth/OndoApiKeyStore.d.ts +21 -0
- package/dist/esm/auth/OndoApiKeyStore.d.ts.map +1 -0
- package/dist/esm/auth/OndoApiKeyStore.js +49 -0
- package/dist/esm/auth/OndoApiKeyStore.js.map +1 -0
- package/dist/esm/auth/hmac.d.ts +20 -0
- package/dist/esm/auth/hmac.d.ts.map +1 -0
- package/dist/esm/auth/hmac.js +19 -0
- package/dist/esm/auth/hmac.js.map +1 -0
- package/dist/esm/auth/index.d.ts +3 -1
- package/dist/esm/auth/index.d.ts.map +1 -1
- package/dist/esm/auth/index.js +3 -1
- package/dist/esm/auth/index.js.map +1 -1
- package/dist/esm/auth/signActions.d.ts +14 -15
- package/dist/esm/auth/signActions.d.ts.map +1 -1
- package/dist/esm/auth/signActions.js +85 -60
- package/dist/esm/auth/signActions.js.map +1 -1
- package/dist/esm/constants.d.ts +24 -0
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.js +24 -0
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/types/auth.d.ts +16 -0
- package/dist/esm/types/auth.d.ts.map +1 -1
- package/dist/esm/utils/apiClient.d.ts +2 -4
- package/dist/esm/utils/apiClient.d.ts.map +1 -1
- package/dist/esm/utils/apiClient.js +2 -4
- package/dist/esm/utils/apiClient.js.map +1 -1
- package/dist/types/OndoProvider.d.ts.map +1 -1
- package/dist/types/accountConfig.d.ts.map +1 -1
- package/dist/types/auth/OndoApiKeyStore.d.ts +21 -0
- package/dist/types/auth/OndoApiKeyStore.d.ts.map +1 -0
- package/dist/types/auth/hmac.d.ts +20 -0
- package/dist/types/auth/hmac.d.ts.map +1 -0
- package/dist/types/auth/index.d.ts +3 -1
- package/dist/types/auth/index.d.ts.map +1 -1
- package/dist/types/auth/signActions.d.ts +14 -15
- package/dist/types/auth/signActions.d.ts.map +1 -1
- package/dist/types/constants.d.ts +24 -0
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/types/auth.d.ts +16 -0
- package/dist/types/types/auth.d.ts.map +1 -1
- package/dist/types/utils/apiClient.d.ts +2 -4
- package/dist/types/utils/apiClient.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/OndoProvider.ts +32 -17
- package/src/accountConfig.ts +18 -3
- package/src/auth/OndoApiKeyStore.ts +64 -0
- package/src/auth/hmac.ts +45 -0
- package/src/auth/index.ts +2 -1
- package/src/auth/signActions.ts +126 -77
- package/src/constants.ts +28 -0
- package/src/types/auth.ts +17 -0
- package/src/utils/apiClient.ts +2 -4
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { readValidatedRecord, type StorageAdapter } from '@lifi/perps-sdk'
|
|
2
|
+
import type { Address } from 'viem'
|
|
3
|
+
import type { OndoApiKey } from '../types/auth.js'
|
|
4
|
+
|
|
5
|
+
// Keys are namespaced by environment host as well as address: a production
|
|
6
|
+
// API key is meaningless against the sandbox, and both stores may share one
|
|
7
|
+
// localStorage.
|
|
8
|
+
|
|
9
|
+
const STORAGE_PREFIX = 'lifi-perps-ondo-apikey'
|
|
10
|
+
|
|
11
|
+
const isOndoApiKey = (value: unknown): value is OndoApiKey => {
|
|
12
|
+
if (typeof value !== 'object' || value === null) {
|
|
13
|
+
return false
|
|
14
|
+
}
|
|
15
|
+
const { keyId, apiSecret, name, createdAt, scopes } = value as Record<
|
|
16
|
+
string,
|
|
17
|
+
unknown
|
|
18
|
+
>
|
|
19
|
+
return (
|
|
20
|
+
typeof keyId === 'string' &&
|
|
21
|
+
keyId.length > 0 &&
|
|
22
|
+
typeof apiSecret === 'string' &&
|
|
23
|
+
apiSecret.length > 0 &&
|
|
24
|
+
typeof name === 'string' &&
|
|
25
|
+
typeof createdAt === 'string' &&
|
|
26
|
+
Array.isArray(scopes) &&
|
|
27
|
+
scopes.every((scope) => typeof scope === 'string')
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Persists the Ondo trading API key per wallet address and environment via a
|
|
33
|
+
* `StorageAdapter`, mirroring {@link OndoTokenStore}. The record holds the
|
|
34
|
+
* `apiSecret` returned only at creation; a poisoned record reads back as absent
|
|
35
|
+
* (and is evicted), so callers can treat `null` uniformly as "mint a key".
|
|
36
|
+
*
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export class OndoApiKeyStore {
|
|
40
|
+
private readonly storage: StorageAdapter
|
|
41
|
+
private readonly host: string
|
|
42
|
+
|
|
43
|
+
constructor(storage: StorageAdapter, baseUrl: string) {
|
|
44
|
+
this.storage = storage
|
|
45
|
+
this.host = new URL(baseUrl).host
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private storageKey(address: Address): string {
|
|
49
|
+
return `${STORAGE_PREFIX}:${this.host}:${address.toLowerCase()}`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async get(address: Address): Promise<OndoApiKey | null> {
|
|
53
|
+
const key = this.storageKey(address)
|
|
54
|
+
return (await readValidatedRecord(this.storage, key, isOndoApiKey)) ?? null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async set(address: Address, apiKey: OndoApiKey): Promise<void> {
|
|
58
|
+
await this.storage.set(this.storageKey(address), JSON.stringify(apiKey))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async remove(address: Address): Promise<void> {
|
|
62
|
+
await this.storage.remove(this.storageKey(address))
|
|
63
|
+
}
|
|
64
|
+
}
|
package/src/auth/hmac.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** @internal */
|
|
2
|
+
export interface OndoHmacRequest {
|
|
3
|
+
/** Milliseconds since epoch; Ondo enforces a 30-second signing window. */
|
|
4
|
+
timestampMs: number
|
|
5
|
+
method: string
|
|
6
|
+
/** Venue-relative path including any query string. */
|
|
7
|
+
pathWithQuery: string
|
|
8
|
+
/** Pre-serialized body, signed verbatim; empty for bodyless requests. */
|
|
9
|
+
body?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const encoder = new TextEncoder()
|
|
13
|
+
|
|
14
|
+
const toHex = (buffer: ArrayBuffer): string =>
|
|
15
|
+
Array.from(new Uint8Array(buffer))
|
|
16
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
17
|
+
.join('')
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Compute Ondo's per-request HMAC-SHA256 signature, hex-encoded. The signed
|
|
21
|
+
* message concatenates timestamp, upper-cased method, path-with-query, and the
|
|
22
|
+
* verbatim body with no separators.
|
|
23
|
+
*
|
|
24
|
+
* @param apiSecret - the API key's secret, used as the HMAC key.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export async function hmacSignRequest(
|
|
28
|
+
apiSecret: string,
|
|
29
|
+
request: OndoHmacRequest
|
|
30
|
+
): Promise<string> {
|
|
31
|
+
const message = `${request.timestampMs}${request.method.toUpperCase()}${request.pathWithQuery}${request.body ?? ''}`
|
|
32
|
+
const key = await crypto.subtle.importKey(
|
|
33
|
+
'raw',
|
|
34
|
+
encoder.encode(apiSecret),
|
|
35
|
+
{ name: 'HMAC', hash: 'SHA-256' },
|
|
36
|
+
false,
|
|
37
|
+
['sign']
|
|
38
|
+
)
|
|
39
|
+
const signature = await crypto.subtle.sign(
|
|
40
|
+
'HMAC',
|
|
41
|
+
key,
|
|
42
|
+
encoder.encode(message)
|
|
43
|
+
)
|
|
44
|
+
return toHex(signature)
|
|
45
|
+
}
|
package/src/auth/index.ts
CHANGED
|
@@ -4,9 +4,10 @@ export {
|
|
|
4
4
|
completeSiweLogin,
|
|
5
5
|
type OndoSiweChallenge,
|
|
6
6
|
} from './completeSiweLogin.js'
|
|
7
|
+
export { hmacSignRequest, type OndoHmacRequest } from './hmac.js'
|
|
8
|
+
export { OndoApiKeyStore } from './OndoApiKeyStore.js'
|
|
7
9
|
export { OndoTokenStore } from './OndoTokenStore.js'
|
|
8
10
|
export {
|
|
9
|
-
executeOndoRestCallActions,
|
|
10
11
|
type OndoSignActionsDeps,
|
|
11
12
|
ondoSignActions,
|
|
12
13
|
} from './signActions.js'
|
package/src/auth/signActions.ts
CHANGED
|
@@ -1,43 +1,90 @@
|
|
|
1
1
|
import { PerpsError, type SignActionsContext } from '@lifi/perps-sdk'
|
|
2
2
|
import type {
|
|
3
|
-
ActionResult,
|
|
4
3
|
ActionStep,
|
|
5
|
-
|
|
4
|
+
HmacSignedActionStep,
|
|
5
|
+
SessionActionStep,
|
|
6
6
|
SignedActionStep,
|
|
7
7
|
SiweActionStep,
|
|
8
8
|
} from '@lifi/perps-types'
|
|
9
|
-
import { PerpsErrorCode, SigningMethod } from '@lifi/perps-types'
|
|
9
|
+
import { ActionType, PerpsErrorCode, SigningMethod } from '@lifi/perps-types'
|
|
10
10
|
import type { Address } from 'viem'
|
|
11
|
+
import {
|
|
12
|
+
ONDO_API_KEY_NAME,
|
|
13
|
+
ONDO_API_KEY_SCOPES,
|
|
14
|
+
ONDO_PRIVACY_VERSION,
|
|
15
|
+
ONDO_TERMS_VERSION,
|
|
16
|
+
} from '../constants.js'
|
|
17
|
+
import type { OndoApiKey } from '../types/auth.js'
|
|
11
18
|
import {
|
|
12
19
|
type OndoApiClient,
|
|
13
|
-
type OndoHttpMethod,
|
|
14
20
|
OndoSessionExpiredError,
|
|
15
21
|
} from '../utils/apiClient.js'
|
|
16
22
|
import { completeSiweLogin } from './completeSiweLogin.js'
|
|
23
|
+
import { hmacSignRequest } from './hmac.js'
|
|
24
|
+
import type { OndoApiKeyStore } from './OndoApiKeyStore.js'
|
|
17
25
|
import type { OndoTokenStore } from './OndoTokenStore.js'
|
|
18
26
|
|
|
19
27
|
/** @internal */
|
|
20
28
|
export interface OndoSignActionsDeps {
|
|
21
29
|
client: OndoApiClient
|
|
22
30
|
tokenStore: OndoTokenStore
|
|
31
|
+
apiKeyStore: OndoApiKeyStore
|
|
23
32
|
}
|
|
24
33
|
|
|
25
34
|
const isSiweStep = (step: ActionStep): step is SiweActionStep => 'siwe' in step
|
|
26
35
|
|
|
36
|
+
const isSessionStep = (step: ActionStep): step is SessionActionStep =>
|
|
37
|
+
'session' in step
|
|
38
|
+
|
|
27
39
|
const hasRequest = (
|
|
28
40
|
step: ActionStep
|
|
29
41
|
): step is Extract<ActionStep, { request: unknown }> => 'request' in step
|
|
30
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Fetch the stored trading API key, minting one on first use. Minting is
|
|
45
|
+
* JWT-authorized (`POST /v1/api_keys`); the returned record — including the
|
|
46
|
+
* `apiSecret` the venue reveals only once — is stored immediately. An absent
|
|
47
|
+
* session throws {@link OndoSessionExpiredError} so callers re-run SIWE login.
|
|
48
|
+
*/
|
|
49
|
+
async function ensureApiKey(
|
|
50
|
+
deps: OndoSignActionsDeps,
|
|
51
|
+
address: Address
|
|
52
|
+
): Promise<OndoApiKey> {
|
|
53
|
+
const existing = await deps.apiKeyStore.get(address)
|
|
54
|
+
if (existing !== null) {
|
|
55
|
+
return existing
|
|
56
|
+
}
|
|
57
|
+
const token = await deps.tokenStore.get(address)
|
|
58
|
+
if (token === null) {
|
|
59
|
+
throw new OndoSessionExpiredError(
|
|
60
|
+
`No valid Ondo session token stored for ${address}. Run the SIWE login first.`
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
const apiKey = await deps.client.post<OndoApiKey>(
|
|
64
|
+
'/v1/api_keys',
|
|
65
|
+
{ name: ONDO_API_KEY_NAME, scopes: ONDO_API_KEY_SCOPES },
|
|
66
|
+
{ authToken: token.token }
|
|
67
|
+
)
|
|
68
|
+
await deps.apiKeyStore.set(address, apiKey)
|
|
69
|
+
return apiKey
|
|
70
|
+
}
|
|
71
|
+
|
|
31
72
|
/**
|
|
32
73
|
* Ondo's `signActions` arms.
|
|
33
74
|
*
|
|
34
|
-
* `SIWE` signs the backend-built ERC-4361 challenge with the user's wallet
|
|
35
|
-
*
|
|
75
|
+
* `SIWE` signs the backend-built ERC-4361 challenge with the user's wallet and
|
|
76
|
+
* completes the login directly against Ondo — the returned session JWT is
|
|
36
77
|
* persisted in the token store and never transits the LI.FI backend.
|
|
37
78
|
*
|
|
38
|
-
* `
|
|
39
|
-
*
|
|
40
|
-
*
|
|
79
|
+
* `SESSION` executes client-only setup steps directly against the venue with
|
|
80
|
+
* the stored session token, keyed on the step's action — the marker steps
|
|
81
|
+
* carry no request material by design. Returns no signed steps, so
|
|
82
|
+
* `executeAction` is skipped.
|
|
83
|
+
*
|
|
84
|
+
* `HMAC` computes a per-request HMAC-SHA256 signature over each request step
|
|
85
|
+
* from the client-held API key (minting one on first use), attaching the
|
|
86
|
+
* `hmac` material. The signed step rides the normal `executeAction` path; the
|
|
87
|
+
* API secret itself never leaves the client.
|
|
41
88
|
*
|
|
42
89
|
* @public
|
|
43
90
|
*/
|
|
@@ -77,84 +124,86 @@ export async function ondoSignActions(
|
|
|
77
124
|
return signed
|
|
78
125
|
}
|
|
79
126
|
|
|
80
|
-
case SigningMethod.
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
127
|
+
case SigningMethod.HMAC: {
|
|
128
|
+
const apiKey = await ensureApiKey(deps, address)
|
|
129
|
+
return Promise.all(
|
|
130
|
+
steps.map(async (step): Promise<HmacSignedActionStep> => {
|
|
131
|
+
if (!hasRequest(step)) {
|
|
132
|
+
throw new PerpsError(
|
|
133
|
+
PerpsErrorCode.SDKError,
|
|
134
|
+
`Ondo received a step without a request ('${step.action}') under the hmac signing method.`
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
// Stamped immediately before executeAction; Ondo enforces a 30s window.
|
|
138
|
+
const timestampMs = Date.now()
|
|
139
|
+
const signature = await hmacSignRequest(apiKey.apiSecret, {
|
|
140
|
+
timestampMs,
|
|
141
|
+
method: step.request.method,
|
|
142
|
+
pathWithQuery: step.request.path,
|
|
143
|
+
body: step.request.body,
|
|
144
|
+
})
|
|
145
|
+
return {
|
|
146
|
+
action: step.action,
|
|
147
|
+
request: step.request,
|
|
148
|
+
hmac: {
|
|
149
|
+
keyId: apiKey.keyId,
|
|
150
|
+
timestampMs,
|
|
151
|
+
signature,
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
case SigningMethod.SESSION: {
|
|
159
|
+
for (const step of steps) {
|
|
160
|
+
if (!isSessionStep(step)) {
|
|
89
161
|
throw new PerpsError(
|
|
90
162
|
PerpsErrorCode.SDKError,
|
|
91
|
-
`Ondo received a non-
|
|
163
|
+
`Ondo received a non-session step ('${step.action}') under the session signing method.`
|
|
92
164
|
)
|
|
93
165
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
166
|
+
switch (step.action) {
|
|
167
|
+
case ActionType.ACCEPT_PROVIDER_TERMS: {
|
|
168
|
+
const token = await deps.tokenStore.get(address)
|
|
169
|
+
if (token === null) {
|
|
170
|
+
throw new OndoSessionExpiredError(
|
|
171
|
+
`No valid Ondo session token stored for ${address}. Run the SIWE login first.`
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
await deps.client.post(
|
|
175
|
+
'/v1/agreement',
|
|
176
|
+
{
|
|
177
|
+
termsVersion: ONDO_TERMS_VERSION,
|
|
178
|
+
privacyVersion: ONDO_PRIVACY_VERSION,
|
|
179
|
+
},
|
|
180
|
+
{ authToken: token.token }
|
|
181
|
+
)
|
|
182
|
+
if (token.newAccount) {
|
|
183
|
+
await deps.tokenStore.set(address, {
|
|
184
|
+
...token,
|
|
185
|
+
newAccount: false,
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
break
|
|
189
|
+
}
|
|
190
|
+
case ActionType.REGISTER_API_KEY:
|
|
191
|
+
await ensureApiKey(deps, address)
|
|
192
|
+
break
|
|
193
|
+
default:
|
|
194
|
+
throw new PerpsError(
|
|
195
|
+
PerpsErrorCode.SDKError,
|
|
196
|
+
`Ondo has no session-step executor for action '${step.action}'.`
|
|
197
|
+
)
|
|
98
198
|
}
|
|
99
|
-
}
|
|
199
|
+
}
|
|
200
|
+
return []
|
|
100
201
|
}
|
|
101
202
|
|
|
102
203
|
default:
|
|
103
204
|
throw new PerpsError(
|
|
104
205
|
PerpsErrorCode.SDKError,
|
|
105
|
-
`Ondo does not sign via '${method}'. Supported methods: siwe,
|
|
206
|
+
`Ondo does not sign via '${method}'. Supported methods: siwe, hmac, session.`
|
|
106
207
|
)
|
|
107
208
|
}
|
|
108
209
|
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Execute credential-bearing REST-call steps directly against Ondo,
|
|
112
|
-
* sequentially — later steps in a batch may depend on earlier ones (e.g.
|
|
113
|
-
* leverage update before order placement), so after the first failure the
|
|
114
|
-
* remainder is skipped rather than executed out of order.
|
|
115
|
-
*
|
|
116
|
-
* @public
|
|
117
|
-
*/
|
|
118
|
-
export async function executeOndoRestCallActions(
|
|
119
|
-
client: OndoApiClient,
|
|
120
|
-
steps: RestCallSignedActionStep[]
|
|
121
|
-
): Promise<ActionResult[]> {
|
|
122
|
-
const results: ActionResult[] = []
|
|
123
|
-
let failed = false
|
|
124
|
-
for (const step of steps) {
|
|
125
|
-
if (failed) {
|
|
126
|
-
results.push({
|
|
127
|
-
action: step.action,
|
|
128
|
-
success: false,
|
|
129
|
-
error: 'Skipped: a preceding step in the batch failed.',
|
|
130
|
-
})
|
|
131
|
-
continue
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
const result = await client.send<unknown>(
|
|
135
|
-
step.request.method as OndoHttpMethod,
|
|
136
|
-
step.request.path,
|
|
137
|
-
{ body: step.request.body, headers: step.headers }
|
|
138
|
-
)
|
|
139
|
-
const orderId =
|
|
140
|
-
typeof result === 'object' &&
|
|
141
|
-
result !== null &&
|
|
142
|
-
typeof (result as { orderId?: unknown }).orderId === 'string'
|
|
143
|
-
? (result as { orderId: string }).orderId
|
|
144
|
-
: undefined
|
|
145
|
-
results.push({
|
|
146
|
-
action: step.action,
|
|
147
|
-
success: true,
|
|
148
|
-
...(orderId === undefined ? {} : { orderId }),
|
|
149
|
-
})
|
|
150
|
-
} catch (err) {
|
|
151
|
-
failed = true
|
|
152
|
-
results.push({
|
|
153
|
-
action: step.action,
|
|
154
|
-
success: false,
|
|
155
|
-
error: err instanceof Error ? err.message : String(err),
|
|
156
|
-
})
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return results
|
|
160
|
-
}
|
package/src/constants.ts
CHANGED
|
@@ -36,3 +36,31 @@ export const ONDO_BASE_FEE_TIER = {
|
|
|
36
36
|
maker: '0.0002',
|
|
37
37
|
taker: '0.0005',
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Name applied to the trading API key the SDK mints on first trading use.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export const ONDO_API_KEY_NAME = 'lifi-perps'
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Scopes requested when minting the trading API key.
|
|
49
|
+
*
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
export const ONDO_API_KEY_SCOPES = ['trade']
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Terms-of-Service version accepted at first login. Venue-owned; current value.
|
|
56
|
+
*
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export const ONDO_TERMS_VERSION = 1
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Privacy-policy version accepted at first login. Venue-owned; current value.
|
|
63
|
+
*
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
export const ONDO_PRIVACY_VERSION = 1
|
package/src/types/auth.ts
CHANGED
|
@@ -30,3 +30,20 @@ export interface OndoAuthToken {
|
|
|
30
30
|
/** True when this login created the Ondo account. */
|
|
31
31
|
newAccount: boolean
|
|
32
32
|
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An Ondo trading API key, as returned by `POST /v1/api_keys` and persisted
|
|
36
|
+
* client-side. `apiSecret` is the HMAC key returned only at creation, so the
|
|
37
|
+
* whole record is stored immediately and never re-fetched.
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export interface OndoApiKey {
|
|
42
|
+
keyId: string
|
|
43
|
+
/** HMAC secret; returned only at creation and kept strictly userland. */
|
|
44
|
+
apiSecret: string
|
|
45
|
+
name: string
|
|
46
|
+
/** ISO-8601 creation timestamp, as returned by the venue. */
|
|
47
|
+
createdAt: string
|
|
48
|
+
scopes: string[]
|
|
49
|
+
}
|
package/src/utils/apiClient.ts
CHANGED
|
@@ -146,10 +146,8 @@ export class OndoApiClient {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
149
|
-
* Arbitrary-method request with caller-prebuilt headers
|
|
150
|
-
*
|
|
151
|
-
* `Authorization` header is attached by `signActions` from the token store.
|
|
152
|
-
* Only GET is ever retried; writes are not idempotent.
|
|
149
|
+
* Arbitrary-method request with caller-prebuilt headers. Only GET is ever
|
|
150
|
+
* retried; writes are not idempotent.
|
|
153
151
|
*/
|
|
154
152
|
async send<T>(
|
|
155
153
|
method: OndoHttpMethod,
|