@coinlist-co/react 0.11.0 → 0.11.1-rc.10770e8
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/{chunk-UIIXXLA7.js → chunk-7CTH4KPU.js} +734 -198
- package/dist/chunk-7CTH4KPU.js.map +1 -0
- package/dist/{chunk-B2HCVPCQ.js → chunk-LSPZETDH.js} +81 -33
- package/dist/chunk-LSPZETDH.js.map +1 -0
- package/dist/chunk-UZUQALFY.js +279 -0
- package/dist/chunk-UZUQALFY.js.map +1 -0
- package/dist/client/index.cjs +5415 -2413
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +2439 -1209
- package/dist/client/index.d.ts +2439 -1209
- package/dist/client/index.js +4457 -2178
- package/dist/client/index.js.map +1 -1
- package/dist/collections-BBI_XydI.d.cts +116 -0
- package/dist/collections-BrX9rRWc.d.ts +116 -0
- package/dist/{config-B5mwS_2l.d.cts → config-CMl1bR3F.d.cts} +1183 -150
- package/dist/{config-B5mwS_2l.d.ts → config-CMl1bR3F.d.ts} +1183 -150
- package/dist/server/index.cjs +1005 -265
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +81 -4
- package/dist/server/index.d.ts +81 -4
- package/dist/server/index.js +120 -51
- package/dist/server/index.js.map +1 -1
- package/dist/shared/index.cjs +798 -204
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.d.cts +98 -16
- package/dist/shared/index.d.ts +98 -16
- package/dist/shared/index.js +22 -6
- package/package.json +3 -2
- package/dist/chunk-B2HCVPCQ.js.map +0 -1
- package/dist/chunk-KDGNDAHA.js +0 -146
- package/dist/chunk-KDGNDAHA.js.map +0 -1
- package/dist/chunk-UIIXXLA7.js.map +0 -1
- package/dist/collections-BhDkYmzV.d.cts +0 -65
- package/dist/collections-CZhHoQHr.d.ts +0 -65
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Hex } from 'viem';
|
|
1
|
+
import { Hash, Hex } from 'viem';
|
|
2
2
|
|
|
3
3
|
declare const __brand: unique symbol;
|
|
4
4
|
type Newtype<Base, Branding> = Base & {
|
|
@@ -20,12 +20,544 @@ declare const ClientId: (value: string) => ClientId;
|
|
|
20
20
|
type ClientSecret = Newtype<string, 'ClientSecret'>;
|
|
21
21
|
declare const ClientSecret: (value: string) => ClientSecret;
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* A classified wallet or transaction failure. The SDK derives this from
|
|
25
|
+
* whatever the {@link EvmWallet} throws, so hosts get a stable, typed error
|
|
26
|
+
* shape regardless of the wallet library underneath.
|
|
27
|
+
*
|
|
28
|
+
* Lives here rather than beside its classifier because it is the failure half
|
|
29
|
+
* of the {@link EvmWallet} contract, and because both `@/shared` and
|
|
30
|
+
* `@/client` name it: {@link LogCause} carries one, and classifying a thrown
|
|
31
|
+
* error into one needs viem's error classes, which are browser-side.
|
|
32
|
+
*/
|
|
33
|
+
type WalletError = {
|
|
34
|
+
type: 'user_rejected';
|
|
35
|
+
} | {
|
|
36
|
+
type: 'insufficient_funds';
|
|
37
|
+
} | {
|
|
38
|
+
type: 'contract_reverted';
|
|
39
|
+
/**
|
|
40
|
+
* What the contract said, when it said anything: a `require` string, a
|
|
41
|
+
* panic description, a custom error's name, or the four-byte selector of
|
|
42
|
+
* an error the ABI could not decode.
|
|
43
|
+
*
|
|
44
|
+
* `null` when a revert carried no data, since the string the RPC node
|
|
45
|
+
* offers in its place is not the contract's - see `classifyWalletError`.
|
|
46
|
+
* Nullable rather than optional so that every arm has to answer the
|
|
47
|
+
* question: "it reverted and said nothing" is a fact about the revert,
|
|
48
|
+
* and a caller should have to read it rather than miss it.
|
|
49
|
+
*
|
|
50
|
+
* Never the custom error's arguments. A name is a compile-time
|
|
51
|
+
* identifier; its operands are runtime values - an address, a balance -
|
|
52
|
+
* and those are `'debug'` material.
|
|
53
|
+
*/
|
|
54
|
+
reason: string | null;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'timeout';
|
|
57
|
+
hash: Hash;
|
|
58
|
+
} | {
|
|
59
|
+
type: 'unknown';
|
|
60
|
+
cause: unknown;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* A {@link WalletError} as it may be reported above `'debug'`: the
|
|
64
|
+
* classification, never the throw.
|
|
65
|
+
*
|
|
66
|
+
* Only the `unknown` arm differs, and it differs because it is the one arm
|
|
67
|
+
* carrying a value the SDK did not author - the raw error the wallet library
|
|
68
|
+
* threw, whose message and metadata hold the transaction's `from`, `to`,
|
|
69
|
+
* `value` and calldata. The other four carry compile-time constants or a
|
|
70
|
+
* server-minted identifier already, so they pass through as they stand.
|
|
71
|
+
*
|
|
72
|
+
* This exists as a type rather than as a scrub some function remembers to
|
|
73
|
+
* apply: `LogCause` names it, so an arm that grew a raw field would fail the
|
|
74
|
+
* build instead of quietly reaching {@link Logger.error}.
|
|
75
|
+
*/
|
|
76
|
+
type RedactedWalletError = Exclude<WalletError, {
|
|
77
|
+
type: 'unknown';
|
|
78
|
+
}> | {
|
|
79
|
+
type: 'unknown';
|
|
80
|
+
};
|
|
81
|
+
declare const RedactedWalletError: {
|
|
82
|
+
fromWalletError: (error: WalletError) => RedactedWalletError;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The observability seam a host implements to see inside the SDK.
|
|
87
|
+
*
|
|
88
|
+
* Pass an implementation as {@link Config.logger} and the SDK reports every
|
|
89
|
+
* request it makes, every failure it classifies, and every state a hook
|
|
90
|
+
* settles into. Leave it out and the SDK logs nothing at all - there is no
|
|
91
|
+
* fallback to `console`, at any level, on any codepath.
|
|
92
|
+
*
|
|
93
|
+
* Four methods over a {@link LogEvent} lambda, plus {@link level}. An event is
|
|
94
|
+
* a constant `msg`, the {@link LogScope} it came from, the accumulated
|
|
95
|
+
* {@link LogBindings}, and a bag of `fields` - so a host forwards structured
|
|
96
|
+
* records rather than parsing strings.
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* const logger: Logger = {
|
|
100
|
+
* level: () => 'info',
|
|
101
|
+
* debug: () => {},
|
|
102
|
+
* info: (event) => sink.info(toRecord(event())),
|
|
103
|
+
* warn: (event) => sink.warn(toRecord(event())),
|
|
104
|
+
* error: (event) => sink.error(toRecord(event())),
|
|
105
|
+
* };
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* {@link pinoClientLogger} and {@link pinoServerLogger} are ready-made
|
|
109
|
+
* implementations over pino, and are what most hosts should reach for.
|
|
110
|
+
*
|
|
111
|
+
* ## Where to run it
|
|
112
|
+
*
|
|
113
|
+
* **Not in production, as the default answer.** Development, tests, staging,
|
|
114
|
+
* and reproducing a reported bug are where this seam earns its keep. Left
|
|
115
|
+
* undefined elsewhere it discloses nothing, and that holds no matter what a
|
|
116
|
+
* later revision of the SDK puts on a line.
|
|
117
|
+
*
|
|
118
|
+
* Where you do run one in production, `'info'` and above is the only sane
|
|
119
|
+
* choice, and the shipped implementations make the alternative unrepresentable
|
|
120
|
+
* rather than merely discouraged: `isDev: false` narrows the level to
|
|
121
|
+
* {@link ProductionLogLevel}, so `'debug'` does not compile. That narrowing is
|
|
122
|
+
* a guard for the partner who ignored this paragraph, not an endorsement of
|
|
123
|
+
* the practice.
|
|
124
|
+
*
|
|
125
|
+
* The distinction worth holding onto: `'info'` and above are **redacted by
|
|
126
|
+
* construction** - see the next section for exactly what that covers, and the
|
|
127
|
+
* type that enforces it. Redacted is a mechanism the SDK can hold itself to. A
|
|
128
|
+
* blanket "safe in production" is a promise about your environment that the
|
|
129
|
+
* SDK is in no position to make, and one that a single future field could
|
|
130
|
+
* quietly break.
|
|
131
|
+
*
|
|
132
|
+
* `'debug'` is for reproducing a bug: a developer's machine, tests, and beta
|
|
133
|
+
* or staging environments where the data flowing through the SDK is not real
|
|
134
|
+
* customer data.
|
|
135
|
+
*
|
|
136
|
+
* ## What each level may disclose
|
|
137
|
+
*
|
|
138
|
+
* **`'debug'` is unredacted. Every other level is not.**
|
|
139
|
+
*
|
|
140
|
+
* At `'debug'` the SDK reports request and response bodies, request headers,
|
|
141
|
+
* the full URL including its query string, and operation parameters
|
|
142
|
+
* **verbatim** - bearer tokens, KYC answers, tax-document fields, wallet
|
|
143
|
+
* signatures, the lot. There is no denylist and no redaction: see ADR-8 for
|
|
144
|
+
* why a partial guarantee was rejected in favour of an honest absence of one.
|
|
145
|
+
*
|
|
146
|
+
* At `'info'`, `'warn'` and `'error'` the SDK emits only its own
|
|
147
|
+
* classification of what happened and identifiers the server minted: a method
|
|
148
|
+
* and a bare path, a status, a duration, a {@link RequestId}, a frontline
|
|
149
|
+
* error code and event id, a {@link LogCause} arm. No request body, no
|
|
150
|
+
* response body, no query string, no host-supplied parameters, and no message
|
|
151
|
+
* text read off a thrown error the SDK did not author.
|
|
152
|
+
*
|
|
153
|
+
* The type carries that boundary rather than merely documenting it:
|
|
154
|
+
* {@link SafeEvent} constrains every field value to a {@link LogValue} scalar,
|
|
155
|
+
* so spreading a body, a DTO or an operation's params into an `info`, `warn`
|
|
156
|
+
* or `error` line does not compile. Only {@link DebugEvent} accepts arbitrary
|
|
157
|
+
* values.
|
|
158
|
+
*
|
|
159
|
+
* The one deliberate exception is an SDK-authored validation message, which
|
|
160
|
+
* quotes the single scalar that failed to map - `Unsupported chain:
|
|
161
|
+
* "solana_mainnet"`. It is a hand-written template naming one offending value,
|
|
162
|
+
* not a payload, and it is the whole reason this seam exists.
|
|
163
|
+
*
|
|
164
|
+
* ## Your responsibility
|
|
165
|
+
*
|
|
166
|
+
* The SDK hands you events. What happens next is yours: **you own the final
|
|
167
|
+
* filtering, redaction and retention** before anything is written to a file, a
|
|
168
|
+
* console, or a third-party sink such as Sentry or Datadog. In particular, if
|
|
169
|
+
* you implement {@link debug} and forward it anywhere durable, you have taken
|
|
170
|
+
* on storing live credentials and personal data, deliberately. Implement
|
|
171
|
+
* `debug` as a no-op - or return a level below it from {@link level} - in any
|
|
172
|
+
* environment where that is not acceptable.
|
|
173
|
+
*
|
|
174
|
+
* **Every event is a lambda, and that is load bearing.** The SDK consults
|
|
175
|
+
* {@link level} first and never invokes the lambda when the level forbids it,
|
|
176
|
+
* so an expensive debug event - a serialized DTO, a loop over balances - costs
|
|
177
|
+
* nothing in production where the level is `'error'` or `'none'`. Build the
|
|
178
|
+
* event inside the lambda, never outside it.
|
|
179
|
+
*
|
|
180
|
+
* ## Every method must be total
|
|
181
|
+
*
|
|
182
|
+
* **None of the five methods may throw, and that includes {@link level}.** The
|
|
183
|
+
* SDK calls them inline, on the codepath of the work it is reporting, and it
|
|
184
|
+
* does not catch them: a `logger.error` that throws while reporting a failed
|
|
185
|
+
* request turns that request's rejection into your logger's exception, and a
|
|
186
|
+
* `level()` that throws breaks the call it was asked about even when nothing
|
|
187
|
+
* else went wrong.
|
|
188
|
+
*
|
|
189
|
+
* That is deliberate. Swallowing would hide a logger that is broken in every
|
|
190
|
+
* environment, and the SDK cannot tell a transport blip in your sink from a
|
|
191
|
+
* bug in your implementation. So the contract is on this side of the seam:
|
|
192
|
+
* catch inside your implementation, and never let an exception out. The
|
|
193
|
+
* shipped pino implementations do exactly that.
|
|
194
|
+
*
|
|
195
|
+
* ```ts
|
|
196
|
+
* error: (event) => {
|
|
197
|
+
* try {
|
|
198
|
+
* const e = event();
|
|
199
|
+
* Sentry.captureMessage(e.msg, { extra: e });
|
|
200
|
+
* } catch {
|
|
201
|
+
* // never rethrow: the SDK is on the other side of this call
|
|
202
|
+
* }
|
|
203
|
+
* },
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
interface Logger {
|
|
207
|
+
/**
|
|
208
|
+
* The most detailed level this logger wants. Consulted before **every** log
|
|
209
|
+
* call, so keep it cheap and pure: return a captured constant or read a
|
|
210
|
+
* plain field. Do not read an environment variable, hit storage, or call
|
|
211
|
+
* out to a feature-flag service here.
|
|
212
|
+
*
|
|
213
|
+
* Returning `'none'` silences the SDK as completely as omitting the logger.
|
|
214
|
+
*
|
|
215
|
+
* **Must not throw.** It is consulted inside every SDK operation, so an
|
|
216
|
+
* exception here fails the operation itself.
|
|
217
|
+
*/
|
|
218
|
+
level(): LogLevel;
|
|
219
|
+
/**
|
|
220
|
+
* Fine-grained detail: request and response bodies, full URLs, headers,
|
|
221
|
+
* operation parameters, hook transitions.
|
|
222
|
+
*
|
|
223
|
+
* **Unredacted.** This is the only level that may carry credentials or
|
|
224
|
+
* personal data, and it always may. Its event is a {@link DebugEvent}, whose
|
|
225
|
+
* fields accept arbitrary values for exactly that reason. Do not forward it
|
|
226
|
+
* to a durable or third-party sink outside development and beta.
|
|
227
|
+
*
|
|
228
|
+
* **Must not throw**, here and on every method below.
|
|
229
|
+
*/
|
|
230
|
+
debug(event: () => DebugEvent): void;
|
|
231
|
+
/** Notable, expected events: a request completing, a flow advancing. */
|
|
232
|
+
info(event: () => SafeEvent): void;
|
|
233
|
+
/**
|
|
234
|
+
* Recoverable trouble: a retried request, a renewed session, a poll tick
|
|
235
|
+
* that failed while the last value still stands.
|
|
236
|
+
*
|
|
237
|
+
* Carries a {@link LogCause} when one was classified, the same as
|
|
238
|
+
* {@link error} does. What separates the two levels is whether anything
|
|
239
|
+
* actually broke, not how much is known about it.
|
|
240
|
+
*/
|
|
241
|
+
warn(event: () => SafeEvent): void;
|
|
242
|
+
/**
|
|
243
|
+
* A failure. {@link SafeEvent.cause} carries what the SDK knows about it,
|
|
244
|
+
* classified into {@link LogCause}, and is absent when the failure is not an
|
|
245
|
+
* error the SDK caught - a flow reporting the step it stopped at, for
|
|
246
|
+
* instance.
|
|
247
|
+
*
|
|
248
|
+
* Every part of the event is SDK-authored classification or server-authored
|
|
249
|
+
* identifiers, so forwarding it as it stands is safe. `scope` says which
|
|
250
|
+
* part of the SDK the line came from, which is what to route or filter on.
|
|
251
|
+
*/
|
|
252
|
+
error(event: () => SafeEvent): void;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* A value the SDK is willing to put in a structured field above `'debug'`.
|
|
256
|
+
*
|
|
257
|
+
* Scalars only, and that is the redaction boundary made structural rather than
|
|
258
|
+
* documentary. Every leak ADR-8 found was an *object* spread onto a line that
|
|
259
|
+
* a host forwards to a tracker - an operation's params, a thrown wallet error,
|
|
260
|
+
* a response body. None of them is assignable to this, so each is now a
|
|
261
|
+
* compile error rather than a review catch.
|
|
262
|
+
*
|
|
263
|
+
* It does not stop a call site writing `{ token: accessToken }`, and it is not
|
|
264
|
+
* meant to: a string is a string. What it stops is the mistake that actually
|
|
265
|
+
* happened.
|
|
266
|
+
*/
|
|
267
|
+
type LogValue = string | number | boolean | null;
|
|
268
|
+
/**
|
|
269
|
+
* Fields safe at every level: SDK-authored classification and server-minted
|
|
270
|
+
* identifiers, constrained to {@link LogValue}.
|
|
271
|
+
*/
|
|
272
|
+
type SafeFields = Readonly<Record<string, LogValue>>;
|
|
273
|
+
/**
|
|
274
|
+
* Fields for `'debug'` only: bodies, headers, full URLs, operation params,
|
|
275
|
+
* raw thrown values. Arbitrary values, because that is the point of the level.
|
|
276
|
+
*
|
|
277
|
+
* The SDK's own implementations render these into a form that cannot fail to
|
|
278
|
+
* serialize - a `bigint`, a cycle or a getter that throws must never turn a
|
|
279
|
+
* log line into a second failure - but they are otherwise passed through.
|
|
280
|
+
*/
|
|
281
|
+
type UnredactedFields = Readonly<Record<string, unknown>>;
|
|
282
|
+
/**
|
|
283
|
+
* One narrowing applied to a logger by {@link InternalLogger.child}.
|
|
284
|
+
*
|
|
285
|
+
* A union of single-key objects rather than a positional `string`, because the
|
|
286
|
+
* three things the SDK narrows by are not the same kind of thing: a request id
|
|
287
|
+
* correlates retries of one wire call, a flow name names an on-chain
|
|
288
|
+
* procedure, a hook name names a React binding. Rendered into one `[SCOPE:x]`
|
|
289
|
+
* prefix they were indistinguishable; as fields they must not be.
|
|
290
|
+
*
|
|
291
|
+
* `requestId` keeps its {@link RequestId} newtype rather than widening to
|
|
292
|
+
* `string` at the seam.
|
|
293
|
+
*/
|
|
294
|
+
type LogBinding = {
|
|
295
|
+
readonly requestId: RequestId;
|
|
296
|
+
} | {
|
|
297
|
+
readonly flow: string;
|
|
298
|
+
} | {
|
|
299
|
+
readonly hook: string;
|
|
300
|
+
} | {
|
|
301
|
+
readonly op: string;
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* Every {@link LogBinding} applied so far, merged. This is what reaches a
|
|
305
|
+
* host, so a line from `prepareOndoSell` carries `flow: 'prepareSell'` as its
|
|
306
|
+
* own key and is filterable without parsing anything.
|
|
307
|
+
*/
|
|
308
|
+
type LogBindings = {
|
|
309
|
+
readonly [K in LogBinding as keyof K]?: K[keyof K];
|
|
310
|
+
};
|
|
311
|
+
type BaseEvent = {
|
|
312
|
+
/**
|
|
313
|
+
* What happened, as a **constant string literal**.
|
|
314
|
+
*
|
|
315
|
+
* Never interpolated. A log aggregator groups by message, so a `msg` that
|
|
316
|
+
* embeds a status, a count or a reason produces one group per distinct
|
|
317
|
+
* value and is not groupable at all. Every varying value belongs in
|
|
318
|
+
* `fields`, which is what a host filters and facets on.
|
|
319
|
+
*
|
|
320
|
+
* This is a convention, not a checked rule: deslop reasons about import
|
|
321
|
+
* edges and cannot see a template literal, and the type-level approximations
|
|
322
|
+
* catch only some interpolations. ADR-8 records why a partial guarantee was
|
|
323
|
+
* refused here as elsewhere.
|
|
324
|
+
*/
|
|
325
|
+
readonly msg: string;
|
|
326
|
+
/**
|
|
327
|
+
* Which part of the SDK reported this. Stamped by
|
|
328
|
+
* {@link internalLogger}, never by a call site.
|
|
329
|
+
*/
|
|
330
|
+
readonly scope: LogScope;
|
|
331
|
+
/** Every {@link LogBinding} applied by {@link InternalLogger.child}. */
|
|
332
|
+
readonly bindings: LogBindings;
|
|
333
|
+
};
|
|
334
|
+
/**
|
|
335
|
+
* An event for `'info'`, `'warn'` and `'error'` - the levels a host may run in
|
|
336
|
+
* production.
|
|
337
|
+
*
|
|
338
|
+
* Its fields are {@link SafeFields}, so nothing but a scalar can reach it.
|
|
339
|
+
*/
|
|
340
|
+
type SafeEvent = BaseEvent & {
|
|
341
|
+
readonly fields: SafeFields;
|
|
342
|
+
/**
|
|
343
|
+
* What the SDK knows about an accompanying failure, classified. Absent when
|
|
344
|
+
* there is nothing to classify.
|
|
345
|
+
*/
|
|
346
|
+
readonly cause?: LogCause;
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* An event for `'debug'`, the unredacted level. Its fields accept anything.
|
|
350
|
+
*/
|
|
351
|
+
type DebugEvent = BaseEvent & {
|
|
352
|
+
readonly fields: UnredactedFields;
|
|
353
|
+
};
|
|
354
|
+
/**
|
|
355
|
+
* How much the SDK may report, from silent to everything.
|
|
356
|
+
*
|
|
357
|
+
* Ordered: each level admits itself and everything before it, so `'info'`
|
|
358
|
+
* shows errors, warnings and info but not debug. `'none'` admits nothing.
|
|
359
|
+
*
|
|
360
|
+
* `'debug'` is the unredacted level, and it is deliberately the bottom of the
|
|
361
|
+
* ladder: the guarantee "`debug` is unredacted and every other level is not"
|
|
362
|
+
* only closes if there is nothing below it. That is why the SDK keeps its own
|
|
363
|
+
* five levels rather than adopting pino's seven, which put `trace` underneath.
|
|
364
|
+
*/
|
|
365
|
+
type LogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
|
|
366
|
+
/**
|
|
367
|
+
* The redacted levels: the only ones to consider running in production.
|
|
368
|
+
*
|
|
369
|
+
* Every level except `'debug'`, which is unredacted by design. Used by the
|
|
370
|
+
* shipped pino implementations to make a production `'debug'` logger
|
|
371
|
+
* unrepresentable rather than merely discouraged - see
|
|
372
|
+
* {@link PinoLoggerOptions}.
|
|
373
|
+
*
|
|
374
|
+
* The name marks which levels are *redacted*, not a verdict that running them
|
|
375
|
+
* in production is safe. The SDK's advice is to leave {@link Config.logger}
|
|
376
|
+
* undefined there; this type is what stops the partner who does not take it
|
|
377
|
+
* from reaching the unredacted level as well.
|
|
378
|
+
*/
|
|
379
|
+
type ProductionLogLevel = Exclude<LogLevel, 'debug'>;
|
|
380
|
+
/**
|
|
381
|
+
* How to build one of the SDK's pino-backed loggers.
|
|
382
|
+
*
|
|
383
|
+
* A union rather than `{ level, isDev }`, and that is the whole point:
|
|
384
|
+
* `{ isDev: false, level: 'debug' }` does not typecheck, so a production
|
|
385
|
+
* build cannot ship a logger that prints bearer tokens to a browser console.
|
|
386
|
+
*
|
|
387
|
+
* `isDev` does exactly one thing - decide whether `'debug'` is a legal level.
|
|
388
|
+
* It changes no formatting: dev output and production output are the same
|
|
389
|
+
* shape, so what you debug is what you ship. Pretty-printing is a pipe the
|
|
390
|
+
* host owns (`node server.js | npx pino-pretty`), not a dependency the SDK
|
|
391
|
+
* takes.
|
|
392
|
+
*/
|
|
393
|
+
type PinoLoggerOptions = {
|
|
394
|
+
readonly isDev: true;
|
|
395
|
+
readonly level: LogLevel;
|
|
396
|
+
} | {
|
|
397
|
+
readonly isDev: false;
|
|
398
|
+
readonly level: ProductionLogLevel;
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* Which part of the SDK a line came from, carried as the `scope` field on
|
|
402
|
+
* every event.
|
|
403
|
+
*
|
|
404
|
+
* It names the seam that **reported** the line, not the layer that raised what
|
|
405
|
+
* it reports: an error from `OFFERS` surfaced by `useOffers` is reported on a
|
|
406
|
+
* `HOOKS` line, because that is the hook telling you what it did with it. The
|
|
407
|
+
* `OFFERS` line for the same error is emitted separately, by the namespace.
|
|
408
|
+
*
|
|
409
|
+
* A closed union rather than a free string so that `ONDO` and `Ondo` cannot
|
|
410
|
+
* both appear, so that adding a namespace without giving it a scope fails to
|
|
411
|
+
* compile, and so that a host can `switch` on it when routing. Anything finer
|
|
412
|
+
* - an operation, a flow, a hook - is a {@link LogBinding} and appears as its
|
|
413
|
+
* own field.
|
|
414
|
+
*/
|
|
415
|
+
type LogScope = 'HTTP' | 'AUTH' | 'OFFERS' | 'REQUIREMENTS' | 'WALLETS' | 'ERC20' | 'TOKEN_SALE' | 'SUPERSTATE' | 'ONDO' | 'TOKENS' | 'SUPPORT' | 'HOOKS';
|
|
416
|
+
/**
|
|
417
|
+
* Correlates every line one logical request produces. The first attempt, each
|
|
418
|
+
* retry, and the re-send after a session renewal all carry the same id, so a
|
|
419
|
+
* failure can be read back to the request that caused it.
|
|
420
|
+
*/
|
|
421
|
+
type RequestId = Newtype<string, 'RequestId'>;
|
|
422
|
+
/**
|
|
423
|
+
* The id frontline keys its own logs by, minted server-side and returned as
|
|
424
|
+
* `event_id` on an error envelope. Quote it when raising a ticket with
|
|
425
|
+
* CoinList support: it is what leads from a partner's log line to the request
|
|
426
|
+
* as the backend saw it.
|
|
427
|
+
*
|
|
428
|
+
* A {@link Newtype} rather than a bare `string` because it sits next to
|
|
429
|
+
* {@link RequestId} and frontline's `code` on the same cause, and the three
|
|
430
|
+
* are not interchangeable: an id swapped for a code reads plausibly and points
|
|
431
|
+
* a support engineer at nothing.
|
|
432
|
+
*/
|
|
433
|
+
type FrontlineEventId = Newtype<string, 'FrontlineEventId'>;
|
|
434
|
+
/**
|
|
435
|
+
* What the SDK knows about a failure, classified.
|
|
436
|
+
*
|
|
437
|
+
* **Safe to forward as it stands.** Every arm is SDK-authored classification
|
|
438
|
+
* or a server-authored identifier: no request or response body, no host-
|
|
439
|
+
* supplied parameter, and no value read off a thrown error the SDK did not
|
|
440
|
+
* author. There is nothing here to strip before handing it to an error
|
|
441
|
+
* tracker, which is deliberate - a `LogCause` reaches {@link Logger.error},
|
|
442
|
+
* the level a host actually runs in production, and a guarantee that depends
|
|
443
|
+
* on the host remembering to strip a field is not a guarantee.
|
|
444
|
+
*
|
|
445
|
+
* It is the SDK's **only** structured classification of a thrown error, and it
|
|
446
|
+
* reaches {@link Logger.warn} as well as {@link Logger.error}: a recoverable
|
|
447
|
+
* failure is no less worth naming than a fatal one, and rendering it into a
|
|
448
|
+
* string instead would have meant interpolating into `msg`.
|
|
449
|
+
*
|
|
450
|
+
* Bodies are a `'debug'`-only disclosure and stay on the `HTTP` lines, which
|
|
451
|
+
* {@link RequestId} points at.
|
|
452
|
+
*
|
|
453
|
+
* The arms are the remedies, not the exception classes: a `validation` cause
|
|
454
|
+
* means the backend sent something the SDK does not understand and is worth
|
|
455
|
+
* reporting to CoinList, while an `invariant` cause means the SDK itself
|
|
456
|
+
* computed something impossible and is worth reporting as an SDK bug. Reading
|
|
457
|
+
* `type` should tell you who has to fix it.
|
|
458
|
+
*
|
|
459
|
+
* It carries no scope of its own. The {@link SafeEvent} it arrives on has one,
|
|
460
|
+
* and a cause could only ever have repeated it: the scope is stamped by the
|
|
461
|
+
* logger that *emits* the line, not by the layer that raised the error, so a
|
|
462
|
+
* `validation` failure from `OFFERS` surfaced by `useOffers` would have been
|
|
463
|
+
* tagged `HOOKS` on the hook's line. Forward the event, not the cause alone.
|
|
464
|
+
*/
|
|
465
|
+
type LogCause =
|
|
466
|
+
/**
|
|
467
|
+
* A request reached the backend and came back non-2xx.
|
|
468
|
+
*
|
|
469
|
+
* Deliberately carries no response body. `requestId` is how you get the
|
|
470
|
+
* rest: the `HTTP` lines for the same request carry the method, the path,
|
|
471
|
+
* the duration, every retry, and at `'debug'` the body itself. `code` and
|
|
472
|
+
* `eventId` are frontline's own - quote `eventId` when raising a ticket with
|
|
473
|
+
* CoinList support.
|
|
474
|
+
*/
|
|
475
|
+
{
|
|
476
|
+
type: 'http';
|
|
477
|
+
requestId: RequestId | null;
|
|
478
|
+
status: number;
|
|
479
|
+
code: string | null;
|
|
480
|
+
eventId: FrontlineEventId | null;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* The wire succeeded; the payload was not a shape the SDK can map.
|
|
484
|
+
*
|
|
485
|
+
* `message` is an SDK-authored template and may quote the single scalar that
|
|
486
|
+
* failed - `Unsupported chain: "solana_mainnet"`, `expires_at: not a date
|
|
487
|
+
* ("13/40/2026")`. That one value is the point of the arm; it is never a
|
|
488
|
+
* body and never a whole field set.
|
|
489
|
+
*/
|
|
490
|
+
| {
|
|
491
|
+
type: 'validation';
|
|
492
|
+
message: string;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* The SDK computed something impossible. An SDK bug - please report it.
|
|
496
|
+
* `message` is an SDK-authored template, like `validation`'s.
|
|
497
|
+
*/
|
|
498
|
+
| {
|
|
499
|
+
type: 'invariant';
|
|
500
|
+
message: string;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Every operand was well-formed and the arithmetic on them still had no
|
|
504
|
+
* answer: a division by zero, a result outside the range its type can hold.
|
|
505
|
+
* `message` is an SDK-authored template, like `validation`'s.
|
|
506
|
+
*
|
|
507
|
+
* Separate from `invariant` because the remedy differs. An `invariant` says
|
|
508
|
+
* the SDK computed something impossible and is a bug to report against the
|
|
509
|
+
* SDK; a `math` says the operation was well-posed and the operands, which
|
|
510
|
+
* came off the wire, admit no result - so it points at the response the same
|
|
511
|
+
* way `validation` does, one step later.
|
|
512
|
+
*/
|
|
513
|
+
| {
|
|
514
|
+
type: 'math';
|
|
515
|
+
message: string;
|
|
516
|
+
}
|
|
517
|
+
/** An API-backed call was made without a logged-in user. */
|
|
518
|
+
| {
|
|
519
|
+
type: 'not-authenticated';
|
|
520
|
+
}
|
|
521
|
+
/** A code path the SDK has not shipped yet. */
|
|
522
|
+
| {
|
|
523
|
+
type: 'not-implemented';
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* The user's wallet, or the chain, refused.
|
|
527
|
+
*
|
|
528
|
+
* {@link RedactedWalletError} rather than the full `WalletError`: its
|
|
529
|
+
* `unknown` arm arrives with its `cause` dropped, that field holding the raw
|
|
530
|
+
* wallet-library error whose message and metadata carry the transaction's
|
|
531
|
+
* `from`, `to`, `value` and calldata. It is still on the flow's own returned
|
|
532
|
+
* result, and on the `'debug'` line the flow seam emits beside this one.
|
|
533
|
+
*
|
|
534
|
+
* A type rather than a scrub applied at the call site, so an arm that grew a
|
|
535
|
+
* raw field would fail the build.
|
|
536
|
+
*/
|
|
537
|
+
| {
|
|
538
|
+
type: 'wallet';
|
|
539
|
+
error: RedactedWalletError;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Something the SDK does not recognise - usually a host-supplied lambda
|
|
543
|
+
* (`getAccessToken`, an {@link EvmWallet} method) throwing, or a
|
|
544
|
+
* network-level `fetch` failure.
|
|
545
|
+
*
|
|
546
|
+
* `name` is the error's class name and nothing else. The message and the
|
|
547
|
+
* thrown value itself are host-authored, so they are a `'debug'` disclosure:
|
|
548
|
+
* the paired debug line renders them in full.
|
|
549
|
+
*/
|
|
550
|
+
| {
|
|
551
|
+
type: 'generic-error';
|
|
552
|
+
name: string;
|
|
553
|
+
};
|
|
554
|
+
|
|
23
555
|
/**
|
|
24
556
|
* The exhaustive chain set: a new {@link EthereumChain} is a compile error
|
|
25
557
|
* here until it is listed, which is what keeps the constructor total.
|
|
26
558
|
*/
|
|
27
559
|
declare const ETHEREUM_CHAINS: Record<EthereumChain, true>;
|
|
28
|
-
type EthereumChain = 'ethereum_mainnet' | 'ethereum_sepolia';
|
|
560
|
+
type EthereumChain = 'ethereum_mainnet' | 'ethereum_sepolia' | 'base_mainnet' | 'base_sepolia';
|
|
29
561
|
/**
|
|
30
562
|
* Validates that a raw backend string names a chain the SDK supports.
|
|
31
563
|
*
|
|
@@ -147,11 +679,25 @@ declare const MAX_UINT_256: bigint;
|
|
|
147
679
|
*/
|
|
148
680
|
type Uint256 = bigint;
|
|
149
681
|
/**
|
|
150
|
-
* Asserts a
|
|
151
|
-
*
|
|
152
|
-
*
|
|
682
|
+
* Asserts a computed bigint falls within uint256 bounds. Use at on-chain
|
|
683
|
+
* arithmetic boundaries (bps math, price computation) where the SDK's own
|
|
684
|
+
* arithmetic could underflow below zero or overflow above 2^256-1.
|
|
685
|
+
*
|
|
686
|
+
* Throws {@link InvariantError}, because reaching it means the SDK computed
|
|
687
|
+
* something no chain could represent. **For a value that came off the wire,
|
|
688
|
+
* use {@link parseUint256} instead**: the backend sending an unrepresentable
|
|
689
|
+
* number is a {@link ValidationError}, and the two have different remedies.
|
|
153
690
|
*/
|
|
154
691
|
declare const assertUint256: (value: bigint) => Uint256;
|
|
692
|
+
/**
|
|
693
|
+
* {@link assertUint256} at a wire boundary: the same bounds check, reported as
|
|
694
|
+
* a {@link ValidationError} against the named field, because a value out of
|
|
695
|
+
* range here is the backend's, not the SDK's.
|
|
696
|
+
*
|
|
697
|
+
* `label` names the field the way a DTO mapper's other failures do, so a log
|
|
698
|
+
* line says which one - `SwapPreview.pay_input_amount`, not `a number`.
|
|
699
|
+
*/
|
|
700
|
+
declare const parseUint256: (value: bigint, label: string) => Uint256;
|
|
155
701
|
type BlockchainAmount = Newtype<{
|
|
156
702
|
raw: Uint256;
|
|
157
703
|
decimals: AssetDecimals;
|
|
@@ -159,7 +705,7 @@ type BlockchainAmount = Newtype<{
|
|
|
159
705
|
/**
|
|
160
706
|
* Constructs a {@link BlockchainAmount} and exposes arithmetic helpers.
|
|
161
707
|
* TypeScript has no operator overloading, so use `BlockchainAmount.add(a, b)`
|
|
162
|
-
* instead of
|
|
708
|
+
* instead of `+`/`-`/`*`/`/` on the objects directly.
|
|
163
709
|
*/
|
|
164
710
|
declare const BlockchainAmount: ((value: {
|
|
165
711
|
raw: Uint256;
|
|
@@ -167,7 +713,57 @@ declare const BlockchainAmount: ((value: {
|
|
|
167
713
|
}) => BlockchainAmount) & {
|
|
168
714
|
add: (a: BlockchainAmount, b: BlockchainAmount) => BlockchainAmount;
|
|
169
715
|
sub: (a: BlockchainAmount, b: BlockchainAmount) => BlockchainAmount;
|
|
716
|
+
mul: typeof multiplyAmounts;
|
|
717
|
+
div: typeof divideAmounts;
|
|
170
718
|
};
|
|
719
|
+
/**
|
|
720
|
+
* `a * b`, denominated in `a`'s decimals - a price times a quantity, an amount
|
|
721
|
+
* times a rate.
|
|
722
|
+
*
|
|
723
|
+
* The exact inverse of {@link divideAmounts}, and it reads the same way round:
|
|
724
|
+
* the answer stays in `a`'s scale and `b`'s divides back out, so the two
|
|
725
|
+
* compose - `mul(div(a, b), b)` is `a` again, short only what truncation took.
|
|
726
|
+
* That is what makes `price x quantity` land in the currency the price was
|
|
727
|
+
* quoted in rather than at some product of two exponents no token uses.
|
|
728
|
+
*
|
|
729
|
+
* The multiplication happens *before* the division by `10^b.decimals`, so the
|
|
730
|
+
* full precision of both operands survives into the one rounding at the end.
|
|
731
|
+
* Like `div` it truncates towards zero on both signs, which is the safe
|
|
732
|
+
* direction for money: a total is never inflated past what the parts hold.
|
|
733
|
+
*
|
|
734
|
+
* Total - unlike `div`, there is nothing here to reject. The scale it divides
|
|
735
|
+
* by is a power of ten, never zero, and a product is not bounds-checked for
|
|
736
|
+
* the same reason a quotient is not: whether one past uint256 is a corrupt
|
|
737
|
+
* response or an expected magnitude belongs to the caller.
|
|
738
|
+
*/
|
|
739
|
+
declare function multiplyAmounts(a: BlockchainAmount, b: BlockchainAmount): BlockchainAmount;
|
|
740
|
+
/**
|
|
741
|
+
* `a / b`, denominated in `a`'s decimals - a price, a ratio, a rate.
|
|
742
|
+
*
|
|
743
|
+
* Unlike {@link combineAmounts}, the two operands may be at different scales,
|
|
744
|
+
* and usually are: dividing dollars by shares is the point of the operation,
|
|
745
|
+
* and the two tokens rarely share an exponent. `b`'s scale divides back out -
|
|
746
|
+
* the numerator is scaled by `10^b.decimals` *before* the division, so nothing
|
|
747
|
+
* is lost to integer truncation early and the quotient lands in `a`'s scale,
|
|
748
|
+
* which is the one the amounts it is rendered beside are in.
|
|
749
|
+
*
|
|
750
|
+
* Truncates towards zero on both signs, which is what BigInt division already
|
|
751
|
+
* does and the safe direction for money: the total a price implies never
|
|
752
|
+
* exceeds, in magnitude, the amount that actually moved.
|
|
753
|
+
*
|
|
754
|
+
* A zero divisor is the only rejection. The quotient is deliberately *not*
|
|
755
|
+
* bounds-checked the way {@link combineAmounts} checks a sum: scaling the
|
|
756
|
+
* numerator carries even legal pairs past uint256 (a maximal amount over a
|
|
757
|
+
* single base unit), and whether that reads as a corrupt response or an
|
|
758
|
+
* expected magnitude is the caller's to judge - see `computeOndoBuyPrice` and
|
|
759
|
+
* `computeOndoSellPrice`, which bounds-check the price they build out of this.
|
|
760
|
+
*
|
|
761
|
+
* @throws MathError when `b` is zero. `add` and `sub` throw a bare `Error`
|
|
762
|
+
* because a scale mismatch is a programming error caught in review; a zero
|
|
763
|
+
* divisor arrives from a server response and is divided by during render, so
|
|
764
|
+
* it is a named failure a screen can catch and map to a failed state.
|
|
765
|
+
*/
|
|
766
|
+
declare function divideAmounts(a: BlockchainAmount, b: BlockchainAmount): BlockchainAmount;
|
|
171
767
|
type AssetSymbol = Newtype<string, 'AssetSymbol'>;
|
|
172
768
|
declare const AssetSymbol: (value: string) => AssetSymbol;
|
|
173
769
|
/**
|
|
@@ -225,6 +821,13 @@ declare const OAuthSession: {
|
|
|
225
821
|
};
|
|
226
822
|
|
|
227
823
|
type HttpRequestAttributes = {
|
|
824
|
+
/**
|
|
825
|
+
* Correlates the log lines of one logical request. Minted by
|
|
826
|
+
* {@link HttpClient} on the first attempt and carried onto every retry and
|
|
827
|
+
* post-renewal re-send by {@link concat}, which is what lets a reader tell
|
|
828
|
+
* three attempts of one request from three separate requests.
|
|
829
|
+
*/
|
|
830
|
+
requestId?: RequestId;
|
|
228
831
|
protected?: boolean;
|
|
229
832
|
userAgent?: boolean;
|
|
230
833
|
idempotencyKey?: boolean;
|
|
@@ -272,10 +875,25 @@ type HttpResponse<TBody = unknown> = {
|
|
|
272
875
|
status: number;
|
|
273
876
|
headers?: Record<string, string>;
|
|
274
877
|
body: TBody | null;
|
|
878
|
+
/**
|
|
879
|
+
* The id of the request that produced this response, stamped by
|
|
880
|
+
* {@link HttpClient} so that whoever turns a non-2xx into an
|
|
881
|
+
* {@link HttpError} can carry it without threading the request alongside.
|
|
882
|
+
* Absent when the response did not come from an `HttpClient`.
|
|
883
|
+
*/
|
|
884
|
+
requestId?: RequestId;
|
|
275
885
|
};
|
|
276
886
|
declare class HttpError<TBody = unknown> extends Error {
|
|
277
887
|
readonly response: HttpResponse<TBody>;
|
|
278
888
|
constructor(response: HttpResponse<TBody>);
|
|
889
|
+
/**
|
|
890
|
+
* Correlates this failure with the `[HTTP]` log lines for the same request,
|
|
891
|
+
* which carry the method, the URL, the duration and every retry. `null` when
|
|
892
|
+
* the response did not come from an {@link HttpClient}.
|
|
893
|
+
*
|
|
894
|
+
* Worth quoting in a bug report: it is what makes a log excerpt readable.
|
|
895
|
+
*/
|
|
896
|
+
get requestId(): RequestId | null;
|
|
279
897
|
}
|
|
280
898
|
/**
|
|
281
899
|
* The machine-readable `code` frontline attaches to an error, or `null` for
|
|
@@ -304,6 +922,15 @@ interface Sender {
|
|
|
304
922
|
|
|
305
923
|
interface SharedNamespaceContext {
|
|
306
924
|
readonly api: Sender;
|
|
925
|
+
/**
|
|
926
|
+
* The host's logger, or `null` when they supplied none.
|
|
927
|
+
*
|
|
928
|
+
* Deliberately the raw port rather than a pre-scoped {@link InternalLogger}:
|
|
929
|
+
* one context serves every namespace, and each namespace owns its own scope.
|
|
930
|
+
* A namespace turns it into something usable in its constructor, with
|
|
931
|
+
* `internalLogger(ctx.logger, 'OFFERS')`.
|
|
932
|
+
*/
|
|
933
|
+
readonly logger: Logger | null;
|
|
307
934
|
ensureUserAuthenticated(): Promise<void>;
|
|
308
935
|
}
|
|
309
936
|
|
|
@@ -430,11 +1057,89 @@ interface Erc20Namespace {
|
|
|
430
1057
|
}
|
|
431
1058
|
declare class Erc20NamespaceImpl implements Erc20Namespace {
|
|
432
1059
|
private readonly ctx;
|
|
1060
|
+
private readonly log;
|
|
433
1061
|
constructor(ctx: SharedNamespaceContext);
|
|
434
1062
|
getAllowance(params: GetTokenAllowanceParams): Promise<TokenAllowance>;
|
|
435
1063
|
getBalance(params: GetTokenBalanceParams): Promise<TokenBalance>;
|
|
436
1064
|
}
|
|
437
1065
|
|
|
1066
|
+
/**
|
|
1067
|
+
* The logging surface SDK code uses. Never exported to hosts: they implement
|
|
1068
|
+
* {@link Logger}, which is deliberately smaller.
|
|
1069
|
+
*/
|
|
1070
|
+
type InternalLogger = {
|
|
1071
|
+
/**
|
|
1072
|
+
* A logger narrowed by one more {@link LogBinding}, which every line it
|
|
1073
|
+
* emits carries as its own field.
|
|
1074
|
+
*/
|
|
1075
|
+
child(binding: LogBinding): InternalLogger;
|
|
1076
|
+
/**
|
|
1077
|
+
* The unredacted level. Request and response bodies, full URLs, headers,
|
|
1078
|
+
* operation params and raw thrown errors belong here and **only** here.
|
|
1079
|
+
*/
|
|
1080
|
+
debug(event: () => InternalDebugEvent): void;
|
|
1081
|
+
info(event: () => InternalSafeEvent): void;
|
|
1082
|
+
warn(event: () => InternalSafeEvent): void;
|
|
1083
|
+
/**
|
|
1084
|
+
* Reports a failure whose cause is already known, or has none. Prefer
|
|
1085
|
+
* {@link failure}, which classifies a thrown error for you.
|
|
1086
|
+
*/
|
|
1087
|
+
error(event: () => InternalSafeEvent): void;
|
|
1088
|
+
/**
|
|
1089
|
+
* Reports a thrown error, classifying it into a {@link LogCause}. Prefer
|
|
1090
|
+
* this over `error` at a `catch`: classification only happens when the level
|
|
1091
|
+
* admits it.
|
|
1092
|
+
*
|
|
1093
|
+
* The `error` line names the error's class but never its message, since an
|
|
1094
|
+
* error the SDK did not author may say anything at all. The verbatim
|
|
1095
|
+
* rendering goes onto a paired `debug` line instead.
|
|
1096
|
+
*
|
|
1097
|
+
* For a failure the SDK recovers from, use {@link warning} instead. An
|
|
1098
|
+
* `error` line a host cannot act on is worse than no line at all: it trains
|
|
1099
|
+
* them to ignore the ones that matter.
|
|
1100
|
+
*/
|
|
1101
|
+
failure(event: () => InternalSafeEvent, error: unknown): void;
|
|
1102
|
+
/**
|
|
1103
|
+
* {@link failure} for trouble that did not break anything: a poll tick that
|
|
1104
|
+
* failed while the last value still stands, a retried request.
|
|
1105
|
+
*
|
|
1106
|
+
* Carries the classified {@link LogCause} exactly as `failure` does. The two
|
|
1107
|
+
* differ in level and in nothing else, because what separates them is
|
|
1108
|
+
* whether anything actually broke - not how much is known about it.
|
|
1109
|
+
*/
|
|
1110
|
+
warning(event: () => InternalSafeEvent, error: unknown): void;
|
|
1111
|
+
/**
|
|
1112
|
+
* Runs one namespace operation with logging around it: the call and its
|
|
1113
|
+
* params at `debug`, and any throw at `error` with the cause classified.
|
|
1114
|
+
* Every line carries `op` as a binding.
|
|
1115
|
+
*
|
|
1116
|
+
* **The params never reach the `error` line.** They routinely hold the
|
|
1117
|
+
* things this SDK must not put in front of a production error tracker - an
|
|
1118
|
+
* app bearer token, a document's signing fields, a wallet signature - and
|
|
1119
|
+
* the `debug` line plus the request id is how you get them back. The type
|
|
1120
|
+
* says so: `params` is `unknown`, which is not a {@link SafeFields} value.
|
|
1121
|
+
*
|
|
1122
|
+
* Always rethrows. Logging observes behaviour, it never changes it.
|
|
1123
|
+
*/
|
|
1124
|
+
wrap<T>(op: string, params: unknown, run: () => Promise<T>): Promise<T>;
|
|
1125
|
+
};
|
|
1126
|
+
/**
|
|
1127
|
+
* What a call site hands to `info`, `warn`, `error`, `failure` or `warning` -
|
|
1128
|
+
* a {@link SafeEvent} minus the scope and bindings the logger stamps itself.
|
|
1129
|
+
*/
|
|
1130
|
+
type InternalSafeEvent = {
|
|
1131
|
+
/** A **constant** string literal. Every varying value belongs in `fields`. */
|
|
1132
|
+
readonly msg: string;
|
|
1133
|
+
readonly fields?: SafeFields;
|
|
1134
|
+
readonly cause?: LogCause;
|
|
1135
|
+
};
|
|
1136
|
+
/** What a call site hands to `debug`. Its fields accept anything. */
|
|
1137
|
+
type InternalDebugEvent = {
|
|
1138
|
+
/** A **constant** string literal. Every varying value belongs in `fields`. */
|
|
1139
|
+
readonly msg: string;
|
|
1140
|
+
readonly fields?: UnredactedFields;
|
|
1141
|
+
};
|
|
1142
|
+
|
|
438
1143
|
/**
|
|
439
1144
|
* The product an offer is checked out through. The backend sends one compound
|
|
440
1145
|
* `{supplier}::{saleType}` string, verbatim as spelled below: a double colon
|
|
@@ -456,6 +1161,12 @@ type OfferDto = {
|
|
|
456
1161
|
logo_url: string;
|
|
457
1162
|
starts_at: string;
|
|
458
1163
|
ends_at: string | null;
|
|
1164
|
+
tokens: OfferTokenDto[];
|
|
1165
|
+
};
|
|
1166
|
+
type OfferTokenDto = {
|
|
1167
|
+
role: 'funding' | 'distribution' | 'swap';
|
|
1168
|
+
chain: string;
|
|
1169
|
+
address: string;
|
|
459
1170
|
};
|
|
460
1171
|
|
|
461
1172
|
type OfferId = Newtype<string, 'OfferId'>;
|
|
@@ -472,10 +1183,20 @@ type Offer = {
|
|
|
472
1183
|
logoUrl: string;
|
|
473
1184
|
startsAt: Date;
|
|
474
1185
|
endsAt: Date | null;
|
|
1186
|
+
tokens: OfferToken[];
|
|
475
1187
|
};
|
|
476
1188
|
declare const Offer: {
|
|
477
1189
|
fromDto: (dto: OfferDto) => Offer;
|
|
478
1190
|
};
|
|
1191
|
+
type TokenRole = 'funding' | 'distribution' | 'swap';
|
|
1192
|
+
type OfferToken = {
|
|
1193
|
+
role: TokenRole;
|
|
1194
|
+
chain: Chain;
|
|
1195
|
+
address: EvmContractAddress;
|
|
1196
|
+
};
|
|
1197
|
+
declare const OfferToken: {
|
|
1198
|
+
fromDto: (dto: OfferTokenDto) => OfferToken;
|
|
1199
|
+
};
|
|
479
1200
|
|
|
480
1201
|
/**
|
|
481
1202
|
* The cursor-paginated envelope every list endpoint returns.
|
|
@@ -563,7 +1284,7 @@ type OfferDetailDto = {
|
|
|
563
1284
|
asset: AssetDto;
|
|
564
1285
|
faqs: OfferDetailFaqDto[];
|
|
565
1286
|
funding_assets: AssetDto[];
|
|
566
|
-
tokens:
|
|
1287
|
+
tokens: OfferTokenDto[];
|
|
567
1288
|
id: string;
|
|
568
1289
|
links: OfferDetailLinkDto[];
|
|
569
1290
|
milestones: OfferDetailMilestoneDto[];
|
|
@@ -608,11 +1329,6 @@ type OfferDetailTermDto = {
|
|
|
608
1329
|
key: string | null;
|
|
609
1330
|
value: string | null;
|
|
610
1331
|
};
|
|
611
|
-
type OfferDetailTokenDto = {
|
|
612
|
-
role: 'funding' | 'distribution' | 'swap';
|
|
613
|
-
chain: string;
|
|
614
|
-
address: string;
|
|
615
|
-
};
|
|
616
1332
|
|
|
617
1333
|
type OfferOptionId = Newtype<string, 'OfferOptionId'>;
|
|
618
1334
|
declare const OfferOptionId: (value: string) => OfferOptionId;
|
|
@@ -684,15 +1400,6 @@ type Milestone = {
|
|
|
684
1400
|
declare const Milestone: {
|
|
685
1401
|
fromDto: (dto: OfferDetailMilestoneDto) => Milestone;
|
|
686
1402
|
};
|
|
687
|
-
type TokenRole = 'funding' | 'distribution' | 'swap';
|
|
688
|
-
type OfferToken = {
|
|
689
|
-
role: TokenRole;
|
|
690
|
-
chain: Chain;
|
|
691
|
-
address: EvmContractAddress;
|
|
692
|
-
};
|
|
693
|
-
declare const OfferToken: {
|
|
694
|
-
fromDto: (dto: OfferDetailTokenDto) => OfferToken;
|
|
695
|
-
};
|
|
696
1403
|
|
|
697
1404
|
/** Unique identifier for a participation. */
|
|
698
1405
|
type ParticipationId = Newtype<string, 'ParticipationId'>;
|
|
@@ -812,6 +1519,7 @@ interface CoinListTokenSaleNamespace {
|
|
|
812
1519
|
}
|
|
813
1520
|
declare class CoinListTokenSaleNamespaceImpl implements CoinListTokenSaleNamespace {
|
|
814
1521
|
private readonly ctx;
|
|
1522
|
+
protected readonly log: InternalLogger;
|
|
815
1523
|
constructor(ctx: SharedNamespaceContext);
|
|
816
1524
|
list(offerId?: OfferId): Promise<Participation[]>;
|
|
817
1525
|
listPage(params: ParticipationsPaginationParams): Promise<PaginatedResponse<Participation>>;
|
|
@@ -855,53 +1563,98 @@ type GetOndoQuoteParams = {
|
|
|
855
1563
|
duration?: OndoQuoteDuration;
|
|
856
1564
|
} & OndoQuoteSize;
|
|
857
1565
|
/**
|
|
858
|
-
* What
|
|
859
|
-
*
|
|
860
|
-
* Sized by `amount` alone - the coin being spent, in its own base units - with
|
|
861
|
-
* no `notionalValue` alternative: the calldata authorises a specific ERC-20
|
|
862
|
-
* pull, so the number that ends up on chain has to be the number the caller
|
|
863
|
-
* meant, not one derived from a dollar figure. It is the **gross**: CoinList's
|
|
864
|
-
* fee comes off it, and Ondo prices the remainder.
|
|
1566
|
+
* What both builders take, before the one field whose meaning forks.
|
|
865
1567
|
*
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
*
|
|
869
|
-
*
|
|
1568
|
+
* There is no funding token and no asset here - frontline resolves both from
|
|
1569
|
+
* the offer, because Ninshubur signs a request bound to them and a caller that
|
|
1570
|
+
* could name them could have CoinList sign for a contract of its own. Which
|
|
1571
|
+
* endpoint was called is what says which of the two `amount` counts.
|
|
870
1572
|
*
|
|
871
|
-
* `chain` is required
|
|
872
|
-
*
|
|
873
|
-
* price. `walletAddress` must be the wallet that will *send* the transaction:
|
|
874
|
-
* the calldata is signed over it, so a transaction built for one wallet and
|
|
875
|
-
* broadcast by another reverts.
|
|
1573
|
+
* `chain` is required although the read params refuse it, because these name a
|
|
1574
|
+
* real contract on a real chain rather than asking Ondo for a price.
|
|
876
1575
|
*/
|
|
877
|
-
type
|
|
1576
|
+
type BuildOndoSwapParamsCore = {
|
|
878
1577
|
symbol: AssetSymbol;
|
|
879
1578
|
chain: EthereumChain;
|
|
880
|
-
/**
|
|
1579
|
+
/**
|
|
1580
|
+
* The wallet that will *send* the transaction, and that receives the other
|
|
1581
|
+
* token. The calldata is signed over it, so a transaction built for one
|
|
1582
|
+
* wallet and broadcast by another reverts.
|
|
1583
|
+
*/
|
|
881
1584
|
walletAddress: EvmWalletAddress;
|
|
1585
|
+
};
|
|
1586
|
+
/**
|
|
1587
|
+
* What it takes to turn an indicative price into signed, fillable calldata for
|
|
1588
|
+
* a purchase: `POST /v1/ondo/swap/buy`.
|
|
1589
|
+
*
|
|
1590
|
+
* Separate from {@link BuildOndoSellParams} although the fields match today,
|
|
1591
|
+
* because `amount` is denominated in a different token on each - which is
|
|
1592
|
+
* frontline's own reason for splitting the endpoint rather than taking a
|
|
1593
|
+
* `side`. Sharing one type would re-merge the distinction the split exists to
|
|
1594
|
+
* make, and the two will diverge the day either side gains a knob.
|
|
1595
|
+
*/
|
|
1596
|
+
type BuildOndoBuyParams = BuildOndoSwapParamsCore & {
|
|
882
1597
|
/**
|
|
883
|
-
* The gross
|
|
1598
|
+
* The **gross** deposit, in the base units of the funding token - the coin
|
|
1599
|
+
* the user chose and approved.
|
|
884
1600
|
*
|
|
885
|
-
*
|
|
1601
|
+
* Sized by `amount` alone, with no `notionalValue` alternative: the calldata
|
|
1602
|
+
* authorises a specific ERC-20 pull, so the number that ends up on chain has
|
|
1603
|
+
* to be the number the caller meant rather than one derived from a dollar
|
|
1604
|
+
* figure. CoinList's fee comes off it, and Ondo prices the remainder.
|
|
1605
|
+
*
|
|
1606
|
+
* Its `decimals` are also what the response's `spend_input_decimals` is
|
|
886
1607
|
* checked against: frontline resolves the funding token from the offer
|
|
887
1608
|
* rather than from this request, so the two are independent answers to the
|
|
888
1609
|
* same question and a disagreement means the wrong token was sized.
|
|
889
1610
|
*/
|
|
890
1611
|
amount: BlockchainAmount;
|
|
891
1612
|
};
|
|
1613
|
+
/**
|
|
1614
|
+
* What it takes to turn an indicative price into signed, fillable calldata for
|
|
1615
|
+
* a sale: `POST /v1/ondo/swap/sell`.
|
|
1616
|
+
*
|
|
1617
|
+
* See {@link BuildOndoBuyParams} for why this is its own type.
|
|
1618
|
+
*/
|
|
1619
|
+
type BuildOndoSellParams = BuildOndoSwapParamsCore & {
|
|
1620
|
+
/**
|
|
1621
|
+
* The quantity of the **asset** to sell, in the asset's own base units - not
|
|
1622
|
+
* in the funding token's, which is the same integer meaning something 1e12
|
|
1623
|
+
* different.
|
|
1624
|
+
*
|
|
1625
|
+
* This is the figure the wallet must have approved: a sale delivers the
|
|
1626
|
+
* asset, so the swap contract pulls it with `transferFrom` exactly as it
|
|
1627
|
+
* pulls the deposit on a purchase.
|
|
1628
|
+
*
|
|
1629
|
+
* Its `decimals` are checked against the response's `spend_input_decimals`,
|
|
1630
|
+
* which frontline reads on-chain from the asset on `chain`. The SDK's own
|
|
1631
|
+
* answer comes from the quote, which resolves the asset on Ethereum mainnet,
|
|
1632
|
+
* so on a testnet these are two independent resolutions of two different
|
|
1633
|
+
* contracts - and the check is what says so.
|
|
1634
|
+
*/
|
|
1635
|
+
amount: BlockchainAmount;
|
|
1636
|
+
};
|
|
892
1637
|
|
|
893
1638
|
/**
|
|
894
1639
|
* Raw JSON models for the Ondo swap endpoints, mirroring
|
|
895
|
-
* `OndoSwapTradingStatus`, `OndoSwapQuote` and `
|
|
896
|
-
* frontline's OpenAPI schema. The two GETs are free to poll: neither spends
|
|
897
|
-
* attestation, so a client may call them while the user edits an order. The
|
|
898
|
-
*
|
|
899
|
-
*
|
|
1640
|
+
* `OndoSwapTradingStatus`, `OndoSwapQuote`, `OndoSwapBuy` and `OndoSwapSell`
|
|
1641
|
+
* in frontline's OpenAPI schema. The two GETs are free to poll: neither spends
|
|
1642
|
+
* an attestation, so a client may call them while the user edits an order. The
|
|
1643
|
+
* two POSTs are not - each spends one and hands back signed calldata with a
|
|
1644
|
+
* deadline.
|
|
1645
|
+
*
|
|
1646
|
+
* **One endpoint per side, and therefore one model per side.** The reads take
|
|
1647
|
+
* a `side` and answer the same shape either way, so they stay single. The
|
|
1648
|
+
* writes do not: a buy commits to an exact quantity, a sell to a range with a
|
|
1649
|
+
* floor beneath it, and `amount` is the funding token on one and the asset on
|
|
1650
|
+
* the other. Only the transport fields mean the same thing on both.
|
|
1651
|
+
* `POST /v1/ondo/swap/transaction` survives as a deprecated alias of the buy
|
|
1652
|
+
* under the old `pay_input_*` names; the SDK does not call it.
|
|
900
1653
|
*
|
|
901
1654
|
* Neither GET takes a `chain`. Ondo runs no sandbox, so every environment
|
|
902
|
-
* prices against Ondo production on Ethereum mainnet. The
|
|
903
|
-
*
|
|
904
|
-
* Sepolia one with the mocked attestation.
|
|
1655
|
+
* prices against Ondo production on Ethereum mainnet. The POSTs do carry one:
|
|
1656
|
+
* they target a real contract, which on every environment but production is
|
|
1657
|
+
* the Sepolia one with the mocked attestation.
|
|
905
1658
|
*/
|
|
906
1659
|
/**
|
|
907
1660
|
* Whether an asset can be traded right now, and the caps if so.
|
|
@@ -964,34 +1717,19 @@ type OndoQuoteDto = {
|
|
|
964
1717
|
price: string;
|
|
965
1718
|
};
|
|
966
1719
|
/**
|
|
967
|
-
*
|
|
968
|
-
* to: `POST /v1/ondo/swap/transaction`.
|
|
969
|
-
*
|
|
970
|
-
* Unlike {@link OndoQuoteDto} this **spends an attestation**, so it is not
|
|
971
|
-
* pollable: one call per order, plus one per user-requested refresh. Frontline
|
|
972
|
-
* also reads the wallet's allowance before asking Ninshubur for anything, so
|
|
973
|
-
* an unapproved wallet is refused here rather than reverting on chain.
|
|
1720
|
+
* The transport half of a built swap, identical on both sides.
|
|
974
1721
|
*
|
|
975
|
-
*
|
|
976
|
-
*
|
|
1722
|
+
* `spend_input_amount` is the only key here whose *token* depends on the side,
|
|
1723
|
+
* and `spend_input_decimals` is what says at what scale. Everything below this
|
|
1724
|
+
* point differs, which is why the two responses are two types rather than one
|
|
1725
|
+
* with nullable halves.
|
|
977
1726
|
*
|
|
978
|
-
*
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
*
|
|
982
|
-
* beyond the amounts comes from that GET or from the offer.
|
|
983
|
-
*
|
|
984
|
-
* Every amount is a uint256 decimal string in one of two scales, and **both
|
|
985
|
-
* scales are on the wire**: `receive_output_amount` is in
|
|
986
|
-
* `receive_output_decimals`, and the other three are in
|
|
987
|
-
* `pay_input_decimals`. Neither is interchangeable with the quote's
|
|
988
|
-
* `asset_decimals`, which answers for a different number - see the two fields
|
|
989
|
-
* below.
|
|
990
|
-
*
|
|
991
|
-
* The response has no `object` envelope. `action` says what to do with the
|
|
992
|
-
* body, matching `AllowWalletResponseDto`.
|
|
1727
|
+
* There is no `object` envelope and no `side` echo. `action` says what to do
|
|
1728
|
+
* with the body, matching `AllowWalletResponseDto`; which trade it encodes is
|
|
1729
|
+
* settled by the endpoint that was called, so nothing on the wire has to say
|
|
1730
|
+
* it and nothing has to be checked against it.
|
|
993
1731
|
*/
|
|
994
|
-
type
|
|
1732
|
+
type OndoSwapDtoCore = {
|
|
995
1733
|
action: 'broadcast_transaction';
|
|
996
1734
|
/** The swap contract the transaction is sent to. */
|
|
997
1735
|
to: string;
|
|
@@ -1005,36 +1743,74 @@ type OndoSwapTransactionDto = {
|
|
|
1005
1743
|
*/
|
|
1006
1744
|
expires_at: string;
|
|
1007
1745
|
/**
|
|
1008
|
-
* Gross amount the wallet
|
|
1009
|
-
*
|
|
1746
|
+
* Gross amount the wallet spends, echoing the requested `amount`, in the
|
|
1747
|
+
* smallest unit of the token this side spends - the funding token on a buy,
|
|
1748
|
+
* the asset on a sell. The approval is compared against this.
|
|
1749
|
+
*
|
|
1750
|
+
* Named `pay_input_amount` on the deprecated
|
|
1751
|
+
* `POST /v1/ondo/swap/transaction`. `pay` was accurate only while a buy was
|
|
1752
|
+
* the sole thing this could encode: a sell delivers the asset rather than
|
|
1753
|
+
* paying for one.
|
|
1010
1754
|
*/
|
|
1011
|
-
|
|
1755
|
+
spend_input_amount: string;
|
|
1012
1756
|
/**
|
|
1013
|
-
* Decimals `
|
|
1757
|
+
* Decimals `spend_input_amount` is counted in.
|
|
1758
|
+
*
|
|
1759
|
+
* Frontline reads it on-chain from the token the side spends, which it
|
|
1760
|
+
* resolves from the offer rather than from anything the caller sent. That
|
|
1761
|
+
* makes it the only published scale for a token the request never names -
|
|
1762
|
+
* and an independent answer to the one the SDK derived when it sized the
|
|
1763
|
+
* order, which is why both builders compare the two.
|
|
1014
1764
|
*
|
|
1015
|
-
*
|
|
1016
|
-
* the
|
|
1017
|
-
*
|
|
1018
|
-
* independent answer to the one the SDK derived when it sized the order,
|
|
1019
|
-
* which is why `buildOndoSwapTransaction` compares the two.
|
|
1765
|
+
* **The same key, two scales.** It counts whichever token the side spends:
|
|
1766
|
+
* the funding token's 6 on a buy, the asset's 18 on a sell. Worth knowing
|
|
1767
|
+
* before integrating against both.
|
|
1020
1768
|
*/
|
|
1021
|
-
|
|
1769
|
+
spend_input_decimals: number;
|
|
1770
|
+
};
|
|
1771
|
+
/**
|
|
1772
|
+
* Signed, ready-to-broadcast calldata for a purchase, and the amounts it
|
|
1773
|
+
* commits to: `POST /v1/ondo/swap/buy`.
|
|
1774
|
+
*
|
|
1775
|
+
* Unlike {@link OndoQuoteDto} this **spends an attestation**, so it is not
|
|
1776
|
+
* pollable: one call per order, plus one per user-requested refresh. Frontline
|
|
1777
|
+
* also reads the wallet's allowance on the funding token before asking
|
|
1778
|
+
* Ninshubur for anything, so an unapproved wallet is refused here rather than
|
|
1779
|
+
* reverting on chain.
|
|
1780
|
+
*
|
|
1781
|
+
* The quantity is attested and exact, with no floor beneath it, which is what
|
|
1782
|
+
* separates a buy from an {@link OndoSellDto}.
|
|
1783
|
+
*
|
|
1784
|
+
* **Carries no identity and no price.** No `chain_id`, `symbol`, `ticker` or
|
|
1785
|
+
* `price` - the request named the first few and frontline drops Ninshubur's
|
|
1786
|
+
* `price` deliberately, because `GET /v1/ondo/swap/quote` already publishes
|
|
1787
|
+
* one under that name at a different scale. Anything the UI needs beyond the
|
|
1788
|
+
* amounts comes from that GET or from the offer.
|
|
1789
|
+
*
|
|
1790
|
+
* Two scales are on the wire: `fee` and `notional_value` are in
|
|
1791
|
+
* `spend_input_decimals`, and `receive_output_amount` is in
|
|
1792
|
+
* `receive_output_decimals`. Neither is interchangeable with the quote's
|
|
1793
|
+
* `asset_decimals`, which answers for a different number.
|
|
1794
|
+
*/
|
|
1795
|
+
type OndoBuyDto = OndoSwapDtoCore & {
|
|
1022
1796
|
/**
|
|
1023
|
-
* CoinList's cut of `
|
|
1024
|
-
*
|
|
1025
|
-
*
|
|
1026
|
-
*
|
|
1797
|
+
* CoinList's cut of `spend_input_amount`, in the same units. `"0"` until
|
|
1798
|
+
* ENG-1718 turns a fee on - frontline rejects a non-zero one today.
|
|
1799
|
+
*
|
|
1800
|
+
* Taken at execution rather than added on top, so the wallet never approves
|
|
1801
|
+
* more than `spend_input_amount`.
|
|
1027
1802
|
*/
|
|
1028
1803
|
fee: string;
|
|
1029
1804
|
/**
|
|
1030
|
-
* `
|
|
1031
|
-
*
|
|
1805
|
+
* `spend_input_amount` less `fee`, in `spend_input_decimals`: the part that
|
|
1806
|
+
* reaches Ondo, what the quantity was priced against, and what the
|
|
1807
|
+
* signature commits to.
|
|
1032
1808
|
*/
|
|
1033
1809
|
notional_value: string;
|
|
1034
1810
|
/**
|
|
1035
|
-
* Quantity of the asset the wallet receives, in the
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1811
|
+
* Quantity of the asset the wallet receives, in the asset's smallest unit.
|
|
1812
|
+
* Scale it by `receive_output_decimals`, not by the funding token's and not
|
|
1813
|
+
* by {@link OndoQuoteDto}'s `asset_decimals`.
|
|
1038
1814
|
*/
|
|
1039
1815
|
receive_output_amount: string;
|
|
1040
1816
|
/**
|
|
@@ -1048,6 +1824,74 @@ type OndoSwapTransactionDto = {
|
|
|
1048
1824
|
*/
|
|
1049
1825
|
receive_output_decimals: number;
|
|
1050
1826
|
};
|
|
1827
|
+
/**
|
|
1828
|
+
* Signed, ready-to-broadcast calldata for a sale, and the range it commits to:
|
|
1829
|
+
* `POST /v1/ondo/swap/sell`.
|
|
1830
|
+
*
|
|
1831
|
+
* Like {@link OndoBuyDto} it **spends an attestation** and expires, so it is
|
|
1832
|
+
* called once on confirmation and never on a timer. Frontline reads the
|
|
1833
|
+
* wallet's allowance on the **asset** before signing - a sell delivers it -
|
|
1834
|
+
* and refuses a short one with a 422 naming that address.
|
|
1835
|
+
*
|
|
1836
|
+
* **A sell commits to a range rather than a quantity.** Ondo settles through
|
|
1837
|
+
* USDon before converting to the settlement token, so the response publishes
|
|
1838
|
+
* what to expect and the floor the calldata enforces, each with the fee
|
|
1839
|
+
* charged at it. There is no `notional_value`: a sell commits on the output
|
|
1840
|
+
* side, so there is no fee-exclusive input to report and frontline declines to
|
|
1841
|
+
* relate numbers Ninshubur did not relate.
|
|
1842
|
+
*
|
|
1843
|
+
* All four amounts below are in `receive_output_decimals`. The one amount that
|
|
1844
|
+
* is not is `spend_input_amount`, in `spend_input_decimals` - see
|
|
1845
|
+
* {@link OndoSwapDtoCore}.
|
|
1846
|
+
*
|
|
1847
|
+
* One thing the response does not say, and the calldata does: the floor signed
|
|
1848
|
+
* into `data` is **gross** of CoinList's fee, so a caller decoding it finds a
|
|
1849
|
+
* larger number than `minimum_quantity`. Both are correct; `minimum_quantity`
|
|
1850
|
+
* is what the wallet actually receives.
|
|
1851
|
+
*/
|
|
1852
|
+
type OndoSellDto = OndoSwapDtoCore & {
|
|
1853
|
+
/**
|
|
1854
|
+
* CoinList's cut at the expected outcome, in the settlement token. Already
|
|
1855
|
+
* deducted from `expected_quantity` rather than charged on top of it.
|
|
1856
|
+
*
|
|
1857
|
+
* `"0"` until ENG-1718 turns a fee on - frontline rejects a non-zero one on
|
|
1858
|
+
* either side today.
|
|
1859
|
+
*/
|
|
1860
|
+
expected_fee: string;
|
|
1861
|
+
/**
|
|
1862
|
+
* What the sale is expected to return, **net of `expected_fee`**, in the
|
|
1863
|
+
* settlement token's smallest unit.
|
|
1864
|
+
*
|
|
1865
|
+
* An expectation rather than a guarantee. What the contract enforces is
|
|
1866
|
+
* {@link OndoSellDto.minimum_quantity}.
|
|
1867
|
+
*/
|
|
1868
|
+
expected_quantity: string;
|
|
1869
|
+
/**
|
|
1870
|
+
* CoinList's cut at the floor, in the same units.
|
|
1871
|
+
*
|
|
1872
|
+
* A different number from `expected_fee` because the two are charged on
|
|
1873
|
+
* different amounts - which is why frontline publishes both rather than one.
|
|
1874
|
+
* This is the one to disclose worst-case cost with.
|
|
1875
|
+
*/
|
|
1876
|
+
minimum_fee: string;
|
|
1877
|
+
/**
|
|
1878
|
+
* The least the wallet can receive, **net of `minimum_fee`**, in the same
|
|
1879
|
+
* units. Below it the transaction reverts on chain.
|
|
1880
|
+
*
|
|
1881
|
+
* Frontline guarantees it is at most `expected_quantity` and greater than
|
|
1882
|
+
* zero. The settlement lands somewhere between the two.
|
|
1883
|
+
*/
|
|
1884
|
+
minimum_quantity: string;
|
|
1885
|
+
/**
|
|
1886
|
+
* Decimals both quantities and both fees are counted in, reported by
|
|
1887
|
+
* whatever priced them rather than looked up from the token.
|
|
1888
|
+
*
|
|
1889
|
+
* Not the same number as {@link OndoQuoteDto}'s `asset_decimals`, which
|
|
1890
|
+
* answers for the asset being sold rather than for the coin the proceeds
|
|
1891
|
+
* arrive in.
|
|
1892
|
+
*/
|
|
1893
|
+
receive_output_decimals: number;
|
|
1894
|
+
};
|
|
1051
1895
|
|
|
1052
1896
|
/**
|
|
1053
1897
|
* Whether an Ondo asset can be traded right now.
|
|
@@ -1092,22 +1936,30 @@ declare const OndoTradingStatus: {
|
|
|
1092
1936
|
* contract's `preview`, and no such contract exists for Ondo yet.
|
|
1093
1937
|
*
|
|
1094
1938
|
* The quote carries no transaction to broadcast and no expiry. Building one is
|
|
1095
|
-
* a separate endpoint that spends an attestation - see
|
|
1096
|
-
* {@link
|
|
1939
|
+
* a separate endpoint per side that spends an attestation - see
|
|
1940
|
+
* {@link OndoBuyTransaction} and {@link OndoSellTransaction}.
|
|
1097
1941
|
*/
|
|
1098
1942
|
type OndoQuote = {
|
|
1099
1943
|
/** Always `ethereum_mainnet`: Ondo runs no sandbox in any environment. */
|
|
1100
1944
|
chain: EthereumChain;
|
|
1101
1945
|
ticker: Ticker;
|
|
1102
|
-
/**
|
|
1946
|
+
/**
|
|
1947
|
+
* Needed to approve or transfer the asset; the quote is the only source.
|
|
1948
|
+
*
|
|
1949
|
+
* **Resolved on Ethereum mainnet**, like everything else on this quote, and
|
|
1950
|
+
* therefore not necessarily the contract the swap pulls from on the chain
|
|
1951
|
+
* the order executes on. Frontline resolves that one per chain and publishes
|
|
1952
|
+
* it nowhere, so on a testnet these are two different tokens. Tracked
|
|
1953
|
+
* against the frontline stack that follows ENG-1756.
|
|
1954
|
+
*/
|
|
1103
1955
|
assetAddress: EvmContractAddress;
|
|
1104
1956
|
/**
|
|
1105
1957
|
* The asset as the quote resolves it, from frontline's own catalogue.
|
|
1106
1958
|
*
|
|
1107
1959
|
* Its `decimals` scale {@link tokenBaseUnits} and nothing else. They are
|
|
1108
|
-
* **not** the scale of
|
|
1109
|
-
* reported by whatever priced
|
|
1110
|
-
*
|
|
1960
|
+
* **not** the scale of a built transaction's spend or output: those are
|
|
1961
|
+
* reported by whatever priced them, the sources are allowed to disagree, and
|
|
1962
|
+
* only the one that produced a number answers for it.
|
|
1111
1963
|
*/
|
|
1112
1964
|
asset: Erc20Asset;
|
|
1113
1965
|
side: OrderBookSide;
|
|
@@ -1123,26 +1975,22 @@ declare const OndoQuote: {
|
|
|
1123
1975
|
fromDto: (dto: OndoQuoteDto) => OndoQuote;
|
|
1124
1976
|
};
|
|
1125
1977
|
/**
|
|
1126
|
-
*
|
|
1127
|
-
*
|
|
1978
|
+
* The half of a built swap that both sides share: the calldata, its deadline,
|
|
1979
|
+
* and what the wallet parts with.
|
|
1128
1980
|
*
|
|
1129
|
-
*
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1134
|
-
*
|
|
1135
|
-
* publishes none of them, and inventing them from the request would assert
|
|
1136
|
-
* what the server resolved rather than report it. What it does publish is the
|
|
1137
|
-
* scale of every amount on it, so a caller needs nothing alongside it to read
|
|
1138
|
-
* the numbers - only to name the asset, which the offer already does.
|
|
1981
|
+
* There is deliberately **no union over the two sides**. Each is built by its
|
|
1982
|
+
* own endpoint and its own namespace method, so a caller never holds one
|
|
1983
|
+
* without knowing which it is, and a union would only re-pose a question the
|
|
1984
|
+
* call site had already answered. What is genuinely common lives here, and
|
|
1985
|
+
* {@link executeOndoSwap} takes this rather than either arm - broadcasting
|
|
1986
|
+
* knows nothing about the direction of the trade.
|
|
1139
1987
|
*
|
|
1140
|
-
*
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1143
|
-
*
|
|
1988
|
+
* `side` is not on this type but on each arm, as a literal the SDK authors
|
|
1989
|
+
* from the method that was called. The wire stopped echoing one when the
|
|
1990
|
+
* endpoint split, and it is still worth carrying: `OndoOrderPlaced` is a union
|
|
1991
|
+
* the SDK builds from both, and that union needs a tag.
|
|
1144
1992
|
*/
|
|
1145
|
-
type
|
|
1993
|
+
type OndoSwapTransactionCore = {
|
|
1146
1994
|
/**
|
|
1147
1995
|
* Broadcast as-is. The `to` is the swap contract, which is also the ERC-20
|
|
1148
1996
|
* spender the user must have approved.
|
|
@@ -1153,16 +2001,51 @@ type OndoSwapTransaction = {
|
|
|
1153
2001
|
* reverts, so callers must compare against it before signing.
|
|
1154
2002
|
*/
|
|
1155
2003
|
expiresAt: Date;
|
|
1156
|
-
/** Gross amount the wallet pays, in the funding token's decimals. */
|
|
1157
|
-
payInputAmount: BlockchainAmount;
|
|
1158
2004
|
/**
|
|
1159
|
-
*
|
|
1160
|
-
* the
|
|
1161
|
-
*
|
|
2005
|
+
* Gross amount the wallet spends, in the decimals of the token this side
|
|
2006
|
+
* spends: the funding token on a buy, the asset on a sell.
|
|
2007
|
+
*
|
|
2008
|
+
* The same field at two scales, which is the whole reason the two sides are
|
|
2009
|
+
* two types. It is also what the approval has to cover.
|
|
2010
|
+
*/
|
|
2011
|
+
spendInputAmount: BlockchainAmount;
|
|
2012
|
+
};
|
|
2013
|
+
/**
|
|
2014
|
+
* A signed, expiring purchase: a funding token in, an exact quantity of the
|
|
2015
|
+
* asset out.
|
|
2016
|
+
*
|
|
2017
|
+
* Distinct from {@link OndoQuote} in three ways that matter: it costs an
|
|
2018
|
+
* attestation to obtain, it expires, and it carries a {@link Tx} the wallet
|
|
2019
|
+
* broadcasts verbatim. Treat it as single-use - once broadcast (or once
|
|
2020
|
+
* `expiresAt` passes) it is spent, and a new one must be built.
|
|
2021
|
+
*
|
|
2022
|
+
* **The quantity is attested and exact, with no floor beneath it.** That is
|
|
2023
|
+
* what separates it from an {@link OndoSellTransaction}, which commits to a
|
|
2024
|
+
* range: nothing here is an estimate.
|
|
2025
|
+
*
|
|
2026
|
+
* **It carries no other identity.** No chain, ticker or asset: the endpoint
|
|
2027
|
+
* publishes none of them, and inventing them from the request would assert
|
|
2028
|
+
* what the server resolved rather than report it. What it does publish is the
|
|
2029
|
+
* scale of every amount on it, so a caller needs nothing alongside it to read
|
|
2030
|
+
* the numbers - only to name the assets, which the offer already does.
|
|
2031
|
+
*
|
|
2032
|
+
* It carries no price either. See `computeOndoBuyPrice`, which derives it from
|
|
2033
|
+
* the amounts the response does carry - the price this transaction fills at,
|
|
2034
|
+
* rather than an indicative one that has since moved.
|
|
2035
|
+
*/
|
|
2036
|
+
type OndoBuyTransaction = OndoSwapTransactionCore & {
|
|
2037
|
+
side: 'buy';
|
|
2038
|
+
/**
|
|
2039
|
+
* CoinList's cut, in `spendInputAmount`'s decimals. Zero until ENG-1718
|
|
2040
|
+
* lands - frontline rejects a non-zero one on either side today.
|
|
2041
|
+
*
|
|
2042
|
+
* Taken at execution rather than added on top, so the approval never has to
|
|
2043
|
+
* cover more than `spendInputAmount`.
|
|
1162
2044
|
*/
|
|
1163
2045
|
fee: BlockchainAmount;
|
|
1164
2046
|
/**
|
|
1165
|
-
* `
|
|
2047
|
+
* `spendInputAmount` less `fee`, in the same decimals: what Ondo priced, and
|
|
2048
|
+
* the numerator of the fill price.
|
|
1166
2049
|
*
|
|
1167
2050
|
* Read from the response rather than subtracted here. Whether the fee comes
|
|
1168
2051
|
* off the deposit or goes on top of it is the server's definition to change,
|
|
@@ -1170,22 +2053,86 @@ type OndoSwapTransaction = {
|
|
|
1170
2053
|
*/
|
|
1171
2054
|
notionalValue: BlockchainAmount;
|
|
1172
2055
|
/**
|
|
1173
|
-
*
|
|
1174
|
-
* reported - not at the {@link OndoQuote}'s.
|
|
2056
|
+
* Quantity of the asset the wallet receives, at the scale whatever priced it
|
|
2057
|
+
* reported - not at the {@link OndoQuote}'s `asset.decimals`.
|
|
1175
2058
|
*/
|
|
1176
2059
|
receiveOutputAmount: BlockchainAmount;
|
|
1177
2060
|
};
|
|
1178
|
-
declare const
|
|
1179
|
-
fromDto: (dto:
|
|
2061
|
+
declare const OndoBuyTransaction: {
|
|
2062
|
+
fromDto: (dto: OndoBuyDto) => OndoBuyTransaction;
|
|
2063
|
+
};
|
|
2064
|
+
/**
|
|
2065
|
+
* One end of the range a sale commits to: what arrives, and what CoinList took
|
|
2066
|
+
* to get it there.
|
|
2067
|
+
*
|
|
2068
|
+
* The two travel together because they are charged against each other -
|
|
2069
|
+
* `quantity` is already **net** of `fee` - and because the pair a caller wants
|
|
2070
|
+
* is always both halves of the same outcome. Grouping them is what makes
|
|
2071
|
+
* "the expected quantity, less the fee at the floor" unrepresentable rather
|
|
2072
|
+
* than merely wrong.
|
|
2073
|
+
*/
|
|
2074
|
+
type OndoSellOutcome = {
|
|
2075
|
+
/** What the wallet receives at this outcome, net of {@link fee}. */
|
|
2076
|
+
quantity: BlockchainAmount;
|
|
2077
|
+
/**
|
|
2078
|
+
* CoinList's cut at this outcome, in the same decimals. Zero until ENG-1718
|
|
2079
|
+
* lands - frontline rejects a non-zero one on either side today.
|
|
2080
|
+
*
|
|
2081
|
+
* Already deducted from {@link quantity} rather than charged on top of it.
|
|
2082
|
+
*/
|
|
2083
|
+
fee: BlockchainAmount;
|
|
2084
|
+
};
|
|
2085
|
+
/**
|
|
2086
|
+
* A signed, expiring sale: the asset in, a settlement coin out, somewhere
|
|
2087
|
+
* between two published outcomes.
|
|
2088
|
+
*
|
|
2089
|
+
* Single-use and expiring for the same reasons as an {@link OndoBuyTransaction},
|
|
2090
|
+
* and obtained the same way - one endpoint, one attestation.
|
|
2091
|
+
*
|
|
2092
|
+
* **A sale commits to a range, not a quantity.** Ondo settles through USDon
|
|
2093
|
+
* before converting to the settlement token, so {@link expected} is what to
|
|
2094
|
+
* expect and {@link minimum} is what the calldata enforces. A screen that
|
|
2095
|
+
* shows only the first presents a firm-looking number the contract may
|
|
2096
|
+
* legitimately fill below.
|
|
2097
|
+
*
|
|
2098
|
+
* There is deliberately no counterpart to a buy's `notionalValue`. A sale
|
|
2099
|
+
* commits on the output side, so frontline reports no fee-exclusive input and
|
|
2100
|
+
* refuses to relate numbers Ninshubur did not relate. What it does relate is
|
|
2101
|
+
* each quantity to the fee beside it, which is why {@link OndoSellOutcome}
|
|
2102
|
+
* pairs them.
|
|
2103
|
+
*
|
|
2104
|
+
* One thing this type cannot see: the floor signed into `tx.data` is gross of
|
|
2105
|
+
* the fee, so a caller decoding the calldata finds a larger number than
|
|
2106
|
+
* `minimum.quantity`. Both are correct; `minimum.quantity` is what the wallet
|
|
2107
|
+
* actually receives.
|
|
2108
|
+
*/
|
|
2109
|
+
type OndoSellTransaction = OndoSwapTransactionCore & {
|
|
2110
|
+
side: 'sell';
|
|
2111
|
+
/** What the sale is expected to return. An expectation, not a guarantee. */
|
|
2112
|
+
expected: OndoSellOutcome;
|
|
2113
|
+
/**
|
|
2114
|
+
* The floor the calldata enforces. A fill below it reverts on chain, so this
|
|
2115
|
+
* - not {@link expected} - is what a seller is actually guaranteed.
|
|
2116
|
+
*/
|
|
2117
|
+
minimum: OndoSellOutcome;
|
|
2118
|
+
};
|
|
2119
|
+
declare const OndoSellTransaction: {
|
|
2120
|
+
fromDto: (dto: OndoSellDto) => OndoSellTransaction;
|
|
1180
2121
|
};
|
|
1181
2122
|
|
|
1182
2123
|
/**
|
|
1183
2124
|
* Ondo swap reads, plus the write that turns one into a fillable transaction.
|
|
1184
2125
|
*
|
|
1185
2126
|
* The two reads are free to poll - neither spends an attestation, so a client
|
|
1186
|
-
* may call them while the user edits an order.
|
|
1187
|
-
*
|
|
1188
|
-
*
|
|
2127
|
+
* may call them while the user edits an order. The two builders are not:
|
|
2128
|
+
* budget one call per order placed, plus one per refresh the user asks for.
|
|
2129
|
+
*
|
|
2130
|
+
* **One builder per side, mirroring the endpoints.** A purchase and a sale
|
|
2131
|
+
* agree on how to broadcast and on nothing else: a purchase commits to an
|
|
2132
|
+
* exact quantity, a sale to a range with a floor beneath it, and `amount` is
|
|
2133
|
+
* the funding token on one and the asset on the other. A single method taking
|
|
2134
|
+
* a `side` would have to return a union the caller then re-narrows, having
|
|
2135
|
+
* already decided which trade it was placing.
|
|
1189
2136
|
*
|
|
1190
2137
|
* **No CoinList fee is applied to a read quote, and no read discloses one.**
|
|
1191
2138
|
* Ondo prices exactly the amount passed. A CoinList approval is fee-inclusive,
|
|
@@ -1200,26 +2147,44 @@ interface OndoNamespace {
|
|
|
1200
2147
|
getTradingStatus(params: GetOndoTradingStatusParams): Promise<OndoTradingStatus>;
|
|
1201
2148
|
getQuote(params: GetOndoQuoteParams): Promise<OndoQuote>;
|
|
1202
2149
|
/**
|
|
1203
|
-
* Builds
|
|
1204
|
-
* returns calldata to broadcast, valid until
|
|
1205
|
-
* {@link
|
|
2150
|
+
* Builds a purchase for a specific wallet and deposit: spends an attestation
|
|
2151
|
+
* and returns calldata to broadcast, valid until
|
|
2152
|
+
* {@link OndoBuyTransaction.expiresAt}.
|
|
1206
2153
|
*
|
|
1207
2154
|
* The wallet must have approved the swap contract to spend `amount` of the
|
|
1208
|
-
* offer's funding token first
|
|
1209
|
-
* Ninshubur for anything, and rejects a short one with a 422 carrying
|
|
1210
|
-
* `code: "insufficient_allowance"`. See `
|
|
2155
|
+
* offer's **funding token** first. Frontline reads that allowance before
|
|
2156
|
+
* asking Ninshubur for anything, and rejects a short one with a 422 carrying
|
|
2157
|
+
* `code: "insufficient_allowance"`. See `prepareBuy` on the client
|
|
1211
2158
|
* namespace, which approves and then builds, in that order.
|
|
1212
2159
|
*
|
|
1213
|
-
*
|
|
2160
|
+
* The tokens themselves are the offer's rather than the caller's to name.
|
|
1214
2161
|
*/
|
|
1215
|
-
|
|
2162
|
+
buildBuyTransaction(params: BuildOndoBuyParams): Promise<OndoBuyTransaction>;
|
|
2163
|
+
/**
|
|
2164
|
+
* Builds a sale for a specific wallet and quantity: spends an attestation
|
|
2165
|
+
* and returns calldata to broadcast, valid until
|
|
2166
|
+
* {@link OndoSellTransaction.expiresAt}.
|
|
2167
|
+
*
|
|
2168
|
+
* The approval this one needs is on the **asset**, not on a stablecoin - a
|
|
2169
|
+
* sale delivers the asset, so the swap contract pulls it with `transferFrom`
|
|
2170
|
+
* exactly as it pulls the deposit on a purchase. Same 422 when it is short,
|
|
2171
|
+
* with a message naming that address. See `prepareSell` on the client
|
|
2172
|
+
* namespace.
|
|
2173
|
+
*
|
|
2174
|
+
* Returns a range rather than a quantity: Ondo settles through USDon before
|
|
2175
|
+
* converting to the settlement token, so disclose
|
|
2176
|
+
* {@link OndoSellTransaction.minimum} and not only `expected`.
|
|
2177
|
+
*/
|
|
2178
|
+
buildSellTransaction(params: BuildOndoSellParams): Promise<OndoSellTransaction>;
|
|
1216
2179
|
}
|
|
1217
2180
|
declare class OndoNamespaceImpl implements OndoNamespace {
|
|
1218
2181
|
private readonly ctx;
|
|
2182
|
+
protected readonly log: InternalLogger;
|
|
1219
2183
|
constructor(ctx: SharedNamespaceContext);
|
|
1220
2184
|
getTradingStatus(params: GetOndoTradingStatusParams): Promise<OndoTradingStatus>;
|
|
1221
2185
|
getQuote(params: GetOndoQuoteParams): Promise<OndoQuote>;
|
|
1222
|
-
|
|
2186
|
+
buildBuyTransaction(params: BuildOndoBuyParams): Promise<OndoBuyTransaction>;
|
|
2187
|
+
buildSellTransaction(params: BuildOndoSellParams): Promise<OndoSellTransaction>;
|
|
1223
2188
|
}
|
|
1224
2189
|
|
|
1225
2190
|
/** Parameters shared by contract reads scoped to a chain. */
|
|
@@ -1272,6 +2237,7 @@ interface SuperstateSwapNamespace {
|
|
|
1272
2237
|
}
|
|
1273
2238
|
declare class SuperstateSwapNamespaceImpl implements SuperstateSwapNamespace {
|
|
1274
2239
|
private readonly ctx;
|
|
2240
|
+
protected readonly log: InternalLogger;
|
|
1275
2241
|
constructor(ctx: SharedNamespaceContext);
|
|
1276
2242
|
getAuthorization(params: GetSwapAuthorizationParams): Promise<SwapAuthorization>;
|
|
1277
2243
|
getPreview(params: GetSwapPreviewParams): Promise<SwapPreview>;
|
|
@@ -1465,6 +2431,7 @@ interface WalletsNamespace {
|
|
|
1465
2431
|
}
|
|
1466
2432
|
declare class WalletsNamespaceImpl implements WalletsNamespace {
|
|
1467
2433
|
private readonly ctx;
|
|
2434
|
+
private readonly log;
|
|
1468
2435
|
constructor(ctx: SharedNamespaceContext);
|
|
1469
2436
|
createOwnershipChallenge(params: CreateWalletOwnershipChallengeParams): Promise<WalletOwnershipChallenge>;
|
|
1470
2437
|
connectExternal(params: ConnectExternalWalletParams): Promise<OfferOptionAddress>;
|
|
@@ -1577,7 +2544,7 @@ declare const Pii: {
|
|
|
1577
2544
|
fromDto: (dto: PiiDto) => Pii;
|
|
1578
2545
|
};
|
|
1579
2546
|
|
|
1580
|
-
type RequirementTypeDto = 'kyc_approved' | '
|
|
2547
|
+
type RequirementTypeDto = 'kyc_approved' | 'external_wallet' | 'whitelisted_wallet' | 'jurisdiction' | 'accreditation' | 'document';
|
|
1581
2548
|
type RequirementDto = {
|
|
1582
2549
|
object: 'requirement';
|
|
1583
2550
|
id: string;
|
|
@@ -1701,6 +2668,7 @@ interface RequirementsNamespace {
|
|
|
1701
2668
|
}
|
|
1702
2669
|
declare class RequirementsNamespaceImpl implements RequirementsNamespace {
|
|
1703
2670
|
protected readonly ctx: SharedNamespaceContext;
|
|
2671
|
+
protected readonly log: InternalLogger;
|
|
1704
2672
|
constructor(ctx: SharedNamespaceContext);
|
|
1705
2673
|
forOffer(offerId: OfferId): Promise<Record<OfferOptionId, Requirement[]>>;
|
|
1706
2674
|
statuses(offerId: OfferId): Promise<RequirementStatusInfo[]>;
|
|
@@ -1738,6 +2706,7 @@ interface OffersNamespace {
|
|
|
1738
2706
|
}
|
|
1739
2707
|
declare class OffersNamespaceImpl implements OffersNamespace {
|
|
1740
2708
|
private readonly ctx;
|
|
2709
|
+
private readonly log;
|
|
1741
2710
|
constructor(ctx: SharedNamespaceContext);
|
|
1742
2711
|
list(): Promise<Offer[]>;
|
|
1743
2712
|
listPage(params: PaginationParams): Promise<PaginatedResponse<Offer>>;
|
|
@@ -1806,6 +2775,16 @@ type NabuChainAssetsDto = {
|
|
|
1806
2775
|
protocol: string;
|
|
1807
2776
|
assets: NabuChainAssetDto[];
|
|
1808
2777
|
};
|
|
2778
|
+
/** The registry's `/assets.json` route: the complete snapshot, every chain. */
|
|
2779
|
+
type NabuRegistryDto = {
|
|
2780
|
+
data_version: string;
|
|
2781
|
+
schema_version: number;
|
|
2782
|
+
chains: Array<{
|
|
2783
|
+
chain: string;
|
|
2784
|
+
protocol: string;
|
|
2785
|
+
assets: NabuChainAssetDto[];
|
|
2786
|
+
}>;
|
|
2787
|
+
};
|
|
1809
2788
|
|
|
1810
2789
|
/**
|
|
1811
2790
|
* An absolute URL to a logo image in the token registry. Registry image URLs
|
|
@@ -1855,6 +2834,13 @@ type TokenMetadata = {
|
|
|
1855
2834
|
declare const TokenMetadata: {
|
|
1856
2835
|
/** `baseUrl` is the registry origin; registry logo URLs are root-relative. */
|
|
1857
2836
|
fromDto: (dto: NabuTokenDto, baseUrl: string) => TokenMetadata;
|
|
2837
|
+
/**
|
|
2838
|
+
* Maps the complete registry snapshot to every token it lists across the
|
|
2839
|
+
* chains this SDK models, skipping native coins and chains outside
|
|
2840
|
+
* {@link EthereumChain} (e.g. Solana) rather than failing on them — the
|
|
2841
|
+
* registry may serve chains ahead of the SDK's type surface.
|
|
2842
|
+
*/
|
|
2843
|
+
fromRegistryDto: (dto: NabuRegistryDto, baseUrl: string) => TokenMetadata[];
|
|
1858
2844
|
/**
|
|
1859
2845
|
* Maps a chain snapshot to the tokens it lists, skipping the chain's native
|
|
1860
2846
|
* coin (`kind: 'COIN'`, no contract address).
|
|
@@ -1865,7 +2851,7 @@ declare const TokenMetadata: {
|
|
|
1865
2851
|
/**
|
|
1866
2852
|
* Token display metadata — name, symbol, decimals, and logos — from
|
|
1867
2853
|
* CoinList's public token registry, keyed by {@link TokenIdentifier} (the
|
|
1868
|
-
* same chain + address pairs `
|
|
2854
|
+
* same chain + address pairs `Offer.tokens` carries).
|
|
1869
2855
|
*
|
|
1870
2856
|
* Unlike the other namespaces, this one is public: no method requires an
|
|
1871
2857
|
* authenticated user, and nothing here touches the CoinList API — reads go to
|
|
@@ -1879,26 +2865,31 @@ interface TokensNamespace {
|
|
|
1879
2865
|
*/
|
|
1880
2866
|
get(token: TokenIdentifier): Promise<TokenMetadata | null>;
|
|
1881
2867
|
/**
|
|
1882
|
-
* Fetches
|
|
1883
|
-
*
|
|
1884
|
-
*
|
|
2868
|
+
* Fetches every token the registry lists, in one request: the complete
|
|
2869
|
+
* snapshot with no `chain`, or one chain's snapshot with it. Prefer this
|
|
2870
|
+
* over calling {@link get} in a loop when displaying a catalogue — two
|
|
2871
|
+
* hundred tokens across three chains is still a single download.
|
|
2872
|
+
*
|
|
2873
|
+
* The complete snapshot spans every chain the registry knows; tokens on
|
|
2874
|
+
* chains this SDK does not model (e.g. Solana) are left out of the result.
|
|
1885
2875
|
*
|
|
1886
|
-
* Unlike {@link get}, a missing
|
|
1887
|
-
*
|
|
1888
|
-
* is a deployment problem, not an empty catalogue.
|
|
2876
|
+
* Unlike {@link get}, a missing snapshot throws rather than returning `[]`:
|
|
2877
|
+
* the registry always publishes the complete snapshot and one per chain it
|
|
2878
|
+
* knows, so an absence is a deployment problem, not an empty catalogue.
|
|
1889
2879
|
*/
|
|
1890
|
-
list(chain
|
|
2880
|
+
list(chain?: EthereumChain): Promise<TokenMetadata[]>;
|
|
1891
2881
|
}
|
|
1892
2882
|
declare class TokensNamespaceImpl implements TokensNamespace {
|
|
1893
2883
|
private readonly api;
|
|
2884
|
+
private readonly log;
|
|
1894
2885
|
/**
|
|
1895
2886
|
* Takes the registry origin rather than a `SharedNamespaceContext`: the
|
|
1896
2887
|
* registry is unauthenticated and on its own host, so the frontline sender
|
|
1897
2888
|
* and the auth check would both be dead weight here.
|
|
1898
2889
|
*/
|
|
1899
|
-
constructor(baseUrl: string);
|
|
2890
|
+
constructor(baseUrl: string, logger?: Logger | null);
|
|
1900
2891
|
get(token: TokenIdentifier): Promise<TokenMetadata | null>;
|
|
1901
|
-
list(chain
|
|
2892
|
+
list(chain?: EthereumChain): Promise<TokenMetadata[]>;
|
|
1902
2893
|
}
|
|
1903
2894
|
|
|
1904
2895
|
interface Config {
|
|
@@ -1921,6 +2912,48 @@ interface Config {
|
|
|
1921
2912
|
* registry.
|
|
1922
2913
|
*/
|
|
1923
2914
|
readonly tokensBaseUrl?: string;
|
|
2915
|
+
/**
|
|
2916
|
+
* Where the SDK reports what it is doing. **Omit it and the SDK logs nothing
|
|
2917
|
+
* at all** - no `console` fallback, at any level, on any codepath. Supply
|
|
2918
|
+
* one and every request, every classified failure and every hook state
|
|
2919
|
+
* transition is reported at the level your logger asks for.
|
|
2920
|
+
*
|
|
2921
|
+
* Absent, the SDK says nothing at all - there is no fallback to `console`,
|
|
2922
|
+
* at any level, on any codepath.
|
|
2923
|
+
*
|
|
2924
|
+
* **Running the SDK's logging in production is not advised.** The safest
|
|
2925
|
+
* posture is to leave this undefined outside development, staging and
|
|
2926
|
+
* incident reproduction: a seam that emits nothing cannot disclose anything,
|
|
2927
|
+
* and that property does not depend on the SDK continuing to get redaction
|
|
2928
|
+
* right.
|
|
2929
|
+
*
|
|
2930
|
+
* If you do run one there, run it at `'info'` or above and know what that
|
|
2931
|
+
* does and does not buy you. Those levels are **redacted by construction**:
|
|
2932
|
+
* they carry only SDK-authored classification and server-authored
|
|
2933
|
+
* identifiers, and the type system holds that line rather than a convention -
|
|
2934
|
+
* an event at those levels accepts scalar fields only, so a body, a DTO or
|
|
2935
|
+
* an operation's parameters cannot be put on one. What the SDK does **not**
|
|
2936
|
+
* give you is a warranty that the result is safe for your environment. The
|
|
2937
|
+
* mechanism is checkable and stated; the conclusion depends on your sink,
|
|
2938
|
+
* your retention and your threat model, and it is yours to draw.
|
|
2939
|
+
*
|
|
2940
|
+
* **`'debug'` is not.** It reports request and response bodies, full URLs,
|
|
2941
|
+
* headers and operation parameters verbatim - bearer tokens, KYC answers,
|
|
2942
|
+
* tax-document fields, wallet signatures - and **the SDK does not redact**.
|
|
2943
|
+
* Run it on a developer's machine, in tests, and in beta or staging
|
|
2944
|
+
* environments where the data flowing through is not real customer data.
|
|
2945
|
+
* The shipped implementations make that structural: built with
|
|
2946
|
+
* `isDev: false`, `'debug'` does not typecheck. Either way, filtering,
|
|
2947
|
+
* redaction and retention at your sink are yours, not the SDK's.
|
|
2948
|
+
*
|
|
2949
|
+
* Every method you implement here **must be total**: the SDK calls them on
|
|
2950
|
+
* the codepath of the work they report and does not catch them, so a logger
|
|
2951
|
+
* that throws fails the operation it was describing.
|
|
2952
|
+
*
|
|
2953
|
+
* See {@link Logger} for the full contract, and {@link pinoClientLogger} or
|
|
2954
|
+
* {@link pinoServerLogger} for a ready-made implementation over pino.
|
|
2955
|
+
*/
|
|
2956
|
+
readonly logger?: Logger;
|
|
1924
2957
|
}
|
|
1925
2958
|
|
|
1926
|
-
export { type
|
|
2959
|
+
export { type OndoQuoteSize as $, AuthorizationCode as A, BlockchainAmount as B, CodeVerifier as C, type OfferType as D, type Erc20Namespace as E, Offer as F, RequirementStatusInfo as G, type RequirementType as H, type RequirementStatusValue as I, OfferOptionAddress as J, RequirementId as K, type Logger as L, type KycLevelName as M, DocumentSubmission as N, OfferId as O, Participation as P, type WalletChallengeType as Q, type RequirementsNamespace as R, type SharedNamespaceContext as S, type TokensNamespace as T, type PinoLoggerOptions as U, OndoTradingStatus as V, type WalletError as W, AssetDecimals as X, type BuildOndoBuyParams as Y, type BuildOndoSellParams as Z, OndoQuote as _, EthereumChain as a, Milestone as a$, OfferOptionAddressId as a0, TokenMetadata as a1, type TokenIdentifier as a2, type DebugEvent as a3, type FrontlineEventId as a4, HttpError as a5, type HttpResponse as a6, KycToken as a7, type LogBinding as a8, type LogBindings as a9, type BuildOndoSwapParamsCore as aA, Chain as aB, ClientId as aC, CodeChallenge as aD, ConnectExternalWalletParams as aE, type CreateKycTokenParams as aF, CreateParticipationParams as aG, CreateWalletOwnershipChallengeParams as aH, Cursor as aI, type DocumentFormType as aJ, type DocumentSubmissionStatus as aK, type DocumentType as aL, ETHEREUM_CHAINS as aM, Erc20NamespaceImpl as aN, FaqItem as aO, type GetOndoQuoteParams as aP, type GetOndoTradingStatusParams as aQ, type GetSwapAuthorizationParams as aR, type GetSwapPreviewParams as aS, type GetTokenAllowanceParams as aT, type GetTokenBalanceParams as aU, HexEncodedTransactionData as aV, Iso2CountryCode as aW, Link as aX, type ListOptionAddressesParams as aY, MAX_ASSET_DECIMALS as aZ, MAX_UINT_256 as a_, type LogCause as aa, type LogLevel as ab, type LogScope as ac, type LogValue as ad, type ProductionLogLevel as ae, RedactedWalletError as af, type RequestId as ag, type SafeEvent as ah, type SafeFields as ai, type UnredactedFields as aj, OAuthSession as ak, ClientCredentialsOAuth as al, ClientSecret as am, type Sender as an, PaginationParams as ao, PaginatedResponse as ap, type Uint256 as aq, KnownAssetSymbol as ar, DecimalString as as, SwapStatus as at, type Newtype as au, type AllowWalletParams as av, AllowWalletResponse as aw, Asset as ax, AssetCode as ay, Blockchain as az, EvmContractAddress as b, OAuthRefreshToken as b0, OfferOption as b1, OfferOptionSlug as b2, OfferSlug as b3, OfferToken as b4, OffersNamespaceImpl as b5, type OndoQuoteDuration as b6, type OndoSellOutcome as b7, PKCEState as b8, type PaginatedResponseDto as b9, type TokenRole as bA, TokensNamespaceImpl as bB, type Tx as bC, WalletAddress as bD, WalletOwnershipChallenge as bE, type WalletProtocol as bF, WalletsNamespaceImpl as bG, apiErrorCode as bH, assertUint256 as bI, parseUint256 as bJ, ParticipationId as ba, type ParticipationStatus as bb, ParticipationsPaginationParams as bc, Pii as bd, PiiAddress as be, PiiJurisdiction as bf, type PiiKind as bg, type QueryParamValue as bh, type QueryParamValues as bi, RedirectUri as bj, type RemoveOptionAddressParams as bk, type RequirementActionNeededReason as bl, SOLANA_CHAINS as bm, STABLE_DECIMALS as bn, SolanaChain as bo, type SubmitDocumentParams as bp, SwapAuthorization as bq, type SwapContractRef as br, SwapPreview as bs, TermItem as bt, Ticker as bu, TokenAllowance as bv, TokenBalance as bw, TokenLogo as bx, type TokenLogoImage as by, TokenLogoUrl as bz, type CoinListTokenSaleNamespace as c, OfferOptionId as d, AssetId as e, CoinListTokenSaleNamespaceImpl as f, type OndoNamespace as g, AssetSymbol as h, OndoBuyTransaction as i, OndoSellTransaction as j, type OndoSwapTransactionCore as k, type OrderBookSide as l, OndoNamespaceImpl as m, type SuperstateSwapNamespace as n, type WalletsNamespace as o, Bps as p, EvmWalletAddress as q, SuperstateSwapNamespaceImpl as r, Requirement as s, RequirementsNamespaceImpl as t, type Config as u, type OAuthAccessToken as v, type OffersNamespace as w, StablecoinSymbol as x, type Erc20Asset as y, OfferDetail as z };
|