@riftresearch/sdk 0.16.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -6
- package/dist/index.d.ts +77 -16
- package/dist/index.js +113 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,14 +42,14 @@ const ethereumPepe = createCurrency({
|
|
|
42
42
|
|
|
43
43
|
// Get a quote
|
|
44
44
|
const { quote, executeSwap } = await sdk.getQuote({
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
fromAsset: Currencies.Ethereum.USDC,
|
|
46
|
+
toAsset: Currencies.Bitcoin.BTC,
|
|
47
47
|
amount: '100000000', // 100 USDC (6 decimals)
|
|
48
48
|
mode: 'exact_input',
|
|
49
49
|
slippageBps: 100, // 1%
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
-
console.log(`Swapping ${quote.
|
|
52
|
+
console.log(`Swapping ${quote.fromAsset.expected} USDC for ${quote.toAsset.expected} sats`)
|
|
53
53
|
console.log(`Fees: $${quote.fees.totalUsd.toFixed(2)}`)
|
|
54
54
|
|
|
55
55
|
// Execute the swap
|
|
@@ -64,8 +64,19 @@ const swap = await executeSwap({
|
|
|
64
64
|
console.log(`Order ID: ${swap.orderId}`)
|
|
65
65
|
|
|
66
66
|
// Check status
|
|
67
|
-
const status = await sdk.
|
|
67
|
+
const status = await sdk.getOrderStatus(swap.orderId)
|
|
68
68
|
console.log(`Status: ${status.status}`)
|
|
69
|
+
|
|
70
|
+
// List orders with filters and cursor pagination
|
|
71
|
+
const page = await sdk.getOrders({
|
|
72
|
+
sender: '0x1234...',
|
|
73
|
+
status: 'unfilled',
|
|
74
|
+
orderType: 'limit',
|
|
75
|
+
limit: 20,
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
console.log(`Fetched ${page.items.length} orders`)
|
|
79
|
+
console.log(`Next cursor: ${page.nextCursor}`)
|
|
69
80
|
```
|
|
70
81
|
|
|
71
82
|
## Limit Orders
|
|
@@ -85,8 +96,8 @@ const walletClient = createWalletClient({ account, chain: base, transport: http(
|
|
|
85
96
|
const sdk = new RiftSdk({ integratorName: 'my-app' })
|
|
86
97
|
|
|
87
98
|
const result = await sdk.createLimitOrder({
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
fromAsset: Currencies.Base.USDC,
|
|
100
|
+
toAsset: Currencies.Bitcoin.BTC,
|
|
90
101
|
pricing: {
|
|
91
102
|
sellAmount: '1000000', // 1 USDC (6 decimals)
|
|
92
103
|
buyAmount: '2500', // 2500 sats
|
package/dist/index.d.ts
CHANGED
|
@@ -108,9 +108,13 @@ interface QuoteResponseBase {
|
|
|
108
108
|
interface ExactInputQuoteResponse extends QuoteResponseBase {
|
|
109
109
|
mode: "exact_input";
|
|
110
110
|
/** The exact input amount specified by the user */
|
|
111
|
-
|
|
111
|
+
fromAsset: SpecifiedAmount;
|
|
112
|
+
/** @deprecated Temporary legacy alias for fromAsset */
|
|
113
|
+
from?: SpecifiedAmount;
|
|
112
114
|
/** The calculated output amount with slippage bound */
|
|
113
|
-
|
|
115
|
+
toAsset: CalculatedOutputAmount;
|
|
116
|
+
/** @deprecated Temporary legacy alias for toAsset */
|
|
117
|
+
to?: CalculatedOutputAmount;
|
|
114
118
|
}
|
|
115
119
|
/**
|
|
116
120
|
* Quote response for exact_output mode.
|
|
@@ -119,9 +123,13 @@ interface ExactInputQuoteResponse extends QuoteResponseBase {
|
|
|
119
123
|
interface ExactOutputQuoteResponse extends QuoteResponseBase {
|
|
120
124
|
mode: "exact_output";
|
|
121
125
|
/** The calculated input amount with slippage bound */
|
|
122
|
-
|
|
126
|
+
fromAsset: CalculatedInputAmount;
|
|
127
|
+
/** @deprecated Temporary legacy alias for fromAsset */
|
|
128
|
+
from?: CalculatedInputAmount;
|
|
123
129
|
/** The exact output amount specified by the user */
|
|
124
|
-
|
|
130
|
+
toAsset: SpecifiedAmount;
|
|
131
|
+
/** @deprecated Temporary legacy alias for toAsset */
|
|
132
|
+
to?: SpecifiedAmount;
|
|
125
133
|
}
|
|
126
134
|
/**
|
|
127
135
|
* Discriminated union of quote responses.
|
|
@@ -184,6 +192,10 @@ interface AnalyticsOrderResponse {
|
|
|
184
192
|
lastSourceUpdateAt: string | null;
|
|
185
193
|
terminalAt: string | null;
|
|
186
194
|
}
|
|
195
|
+
interface AnalyticsOrdersResponse {
|
|
196
|
+
items: AnalyticsOrderResponse[];
|
|
197
|
+
nextCursor: string | null;
|
|
198
|
+
}
|
|
187
199
|
interface ErrorResponse {
|
|
188
200
|
error: string;
|
|
189
201
|
}
|
|
@@ -366,11 +378,13 @@ import { Chain as Chain3 } from "viem";
|
|
|
366
378
|
import { Account, PublicClient, Transport, WalletClient } from "viem";
|
|
367
379
|
import { Chain as Chain2 } from "viem/chains";
|
|
368
380
|
type RiftSwap = AnalyticsOrderResponse;
|
|
381
|
+
type RiftOrdersPage = AnalyticsOrdersResponse;
|
|
382
|
+
type OrderTypeFilter = "market" | "limit";
|
|
369
383
|
interface QuoteParameters {
|
|
370
384
|
/** The currency to swap from */
|
|
371
|
-
|
|
385
|
+
fromAsset: Currency;
|
|
372
386
|
/** The currency to swap to */
|
|
373
|
-
|
|
387
|
+
toAsset: Currency;
|
|
374
388
|
/** Amount in smallest unit (sats for BTC, wei for ETH, etc.) */
|
|
375
389
|
amount: string;
|
|
376
390
|
/** Whether amount refers to input or output */
|
|
@@ -405,9 +419,13 @@ interface QuoteResultBase {
|
|
|
405
419
|
interface ExactInputQuoteResult extends QuoteResultBase {
|
|
406
420
|
mode: "exact_input";
|
|
407
421
|
/** The exact input amount specified by the user */
|
|
408
|
-
|
|
422
|
+
fromAsset: SpecifiedAmount;
|
|
423
|
+
/** @deprecated Temporary legacy alias for fromAsset */
|
|
424
|
+
from?: SpecifiedAmount;
|
|
409
425
|
/** The calculated output amount with slippage bound */
|
|
410
|
-
|
|
426
|
+
toAsset: CalculatedOutputAmount;
|
|
427
|
+
/** @deprecated Temporary legacy alias for toAsset */
|
|
428
|
+
to?: CalculatedOutputAmount;
|
|
411
429
|
}
|
|
412
430
|
/**
|
|
413
431
|
* Quote result for exact_output mode.
|
|
@@ -416,9 +434,13 @@ interface ExactInputQuoteResult extends QuoteResultBase {
|
|
|
416
434
|
interface ExactOutputQuoteResult extends QuoteResultBase {
|
|
417
435
|
mode: "exact_output";
|
|
418
436
|
/** The calculated input amount with slippage bound */
|
|
419
|
-
|
|
437
|
+
fromAsset: CalculatedInputAmount;
|
|
438
|
+
/** @deprecated Temporary legacy alias for fromAsset */
|
|
439
|
+
from?: CalculatedInputAmount;
|
|
420
440
|
/** The exact output amount specified by the user */
|
|
421
|
-
|
|
441
|
+
toAsset: SpecifiedAmount;
|
|
442
|
+
/** @deprecated Temporary legacy alias for toAsset */
|
|
443
|
+
to?: SpecifiedAmount;
|
|
422
444
|
}
|
|
423
445
|
/**
|
|
424
446
|
* Discriminated union of quote results.
|
|
@@ -429,11 +451,35 @@ interface GetQuoteResult {
|
|
|
429
451
|
quote: QuoteResult;
|
|
430
452
|
executeSwap: <chain extends Chain2 | undefined = Chain2 | undefined>(context: ExecuteSwapOptions<chain>) => Promise<SwapResult>;
|
|
431
453
|
}
|
|
454
|
+
type LiquidityLimit = {
|
|
455
|
+
from: Currency;
|
|
456
|
+
to: Currency;
|
|
457
|
+
maxInput: string;
|
|
458
|
+
};
|
|
459
|
+
type LiquidityResponse = {
|
|
460
|
+
limits: LiquidityLimit[];
|
|
461
|
+
};
|
|
432
462
|
interface SwapResult {
|
|
433
463
|
orderId: string;
|
|
434
464
|
status: AnalyticsOrderStatus;
|
|
435
465
|
rift: RiftSwap;
|
|
436
466
|
}
|
|
467
|
+
interface GetOrdersOptions {
|
|
468
|
+
/** Filter by exact sender address */
|
|
469
|
+
sender?: string;
|
|
470
|
+
/** Filter by exact destination address */
|
|
471
|
+
destination?: string;
|
|
472
|
+
/** Filter by exact refund address */
|
|
473
|
+
refund?: string;
|
|
474
|
+
/** Filter by execution type */
|
|
475
|
+
orderType?: OrderTypeFilter;
|
|
476
|
+
/** Filter by coarse public order status */
|
|
477
|
+
status?: AnalyticsOrderStatus;
|
|
478
|
+
/** Page size. The API clamps this between 1 and 100, defaulting to 50. */
|
|
479
|
+
limit?: number;
|
|
480
|
+
/** Opaque cursor returned by a previous getOrders() response */
|
|
481
|
+
cursor?: string;
|
|
482
|
+
}
|
|
437
483
|
type CancelOrderResult = CancelOrderResponse;
|
|
438
484
|
/**
|
|
439
485
|
* Function type for sending Bitcoin.
|
|
@@ -463,8 +509,8 @@ type SendBitcoinFn = (params: {
|
|
|
463
509
|
}) => Promise<void>;
|
|
464
510
|
type ExecuteSwapStepType = "approval" | "transaction" | "signature";
|
|
465
511
|
type CreateLimitOrderOptions<chain extends Chain2 | undefined = Chain2 | undefined> = ExecuteSwapContext<chain> & {
|
|
466
|
-
|
|
467
|
-
|
|
512
|
+
fromAsset: Currency;
|
|
513
|
+
toAsset: Currency;
|
|
468
514
|
pricing: LimitPricing;
|
|
469
515
|
destinationAddress: string;
|
|
470
516
|
refundAddress?: string;
|
|
@@ -524,19 +570,21 @@ declare class RiftSdk {
|
|
|
524
570
|
constructor(options: RiftSdkOptions);
|
|
525
571
|
private logDebug;
|
|
526
572
|
private unwrapEdenResult;
|
|
573
|
+
private normalizeQuoteParameters;
|
|
574
|
+
private normalizeLimitOrderOptions;
|
|
527
575
|
/**
|
|
528
576
|
* Get a quote for a swap and return a function to execute it.
|
|
529
577
|
*
|
|
530
578
|
* @example
|
|
531
579
|
* const { quote, executeSwap } = await sdk.getQuote({
|
|
532
|
-
*
|
|
533
|
-
*
|
|
580
|
+
* fromAsset: Currencies.Base.CBBTC,
|
|
581
|
+
* toAsset: Currencies.Bitcoin.BTC,
|
|
534
582
|
* amount: '100000000', // 1 cbBTC
|
|
535
583
|
* mode: 'exact_input',
|
|
536
584
|
* slippageBps: 100, // 1%
|
|
537
585
|
* })
|
|
538
586
|
*
|
|
539
|
-
* console.log(`You'll receive: ${quote.
|
|
587
|
+
* console.log(`You'll receive: ${quote.toAsset.expected} sats`)
|
|
540
588
|
* const swap = await executeSwap({
|
|
541
589
|
* destinationAddress: 'bc1q...',
|
|
542
590
|
* publicClient,
|
|
@@ -585,8 +633,21 @@ declare class RiftSdk {
|
|
|
585
633
|
/**
|
|
586
634
|
* Get the current status of an order by its ID.
|
|
587
635
|
*/
|
|
636
|
+
getOrderStatus(orderId: string): Promise<AnalyticsOrderResponse>;
|
|
637
|
+
/**
|
|
638
|
+
* @deprecated Use getOrderStatus() instead.
|
|
639
|
+
*/
|
|
588
640
|
getSwapStatus(orderId: string): Promise<AnalyticsOrderResponse>;
|
|
589
641
|
/**
|
|
642
|
+
* List orders through the public `/orders` endpoint with the same filters
|
|
643
|
+
* exposed by the swap-router OpenAPI documentation.
|
|
644
|
+
*/
|
|
645
|
+
getOrders(options?: GetOrdersOptions): Promise<RiftOrdersPage>;
|
|
646
|
+
/**
|
|
647
|
+
* Get the current exact-input liquidity limits exposed by the swap router.
|
|
648
|
+
*/
|
|
649
|
+
getLiquidity(): Promise<LiquidityResponse>;
|
|
650
|
+
/**
|
|
590
651
|
* Cancel a supported limit order through the swap router.
|
|
591
652
|
*
|
|
592
653
|
* The SDK first requests the backend-specific typed-data payload from the
|
|
@@ -596,4 +657,4 @@ declare class RiftSdk {
|
|
|
596
657
|
cancelOrder<chain extends Chain3 | undefined = Chain3 | undefined>(options: CancelOrderOptions<chain>): Promise<CancelOrderResult>;
|
|
597
658
|
}
|
|
598
659
|
declare function createRiftSdk(options: RiftSdkOptions): RiftSdk;
|
|
599
|
-
export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, AnalyticsOrderStatus as SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, QuoteResult, QuoteParameters, NativeToken, LimitPricing, GetQuoteResult, ExecutionStep, ExecutionAction, ExecuteSwapStepType, ExecuteSwapOptions, ExecuteSwapOnExecuteStepCallback, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, CreateLimitOrderOptions, Chain, CancelOrderResult, CancelOrderOptions, BtcTransferStep, BtcTransferKind, BitcoinChain };
|
|
660
|
+
export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, AnalyticsOrderStatus as SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, RiftOrdersPage, QuoteResult, QuoteParameters, OrderTypeFilter, NativeToken, LiquidityResponse, LiquidityLimit, LimitPricing, GetQuoteResult, GetOrdersOptions, ExecutionStep, ExecutionAction, ExecuteSwapStepType, ExecuteSwapOptions, ExecuteSwapOnExecuteStepCallback, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, CreateLimitOrderOptions, Chain, CancelOrderResult, CancelOrderOptions, BtcTransferStep, BtcTransferKind, BitcoinChain };
|
package/dist/index.js
CHANGED
|
@@ -183,6 +183,20 @@ import {
|
|
|
183
183
|
} from "viem";
|
|
184
184
|
|
|
185
185
|
// src/client.ts
|
|
186
|
+
function buildQueryString(query) {
|
|
187
|
+
if (!query) {
|
|
188
|
+
return "";
|
|
189
|
+
}
|
|
190
|
+
const searchParams = new URLSearchParams;
|
|
191
|
+
for (const [key, value] of Object.entries(query)) {
|
|
192
|
+
if (value === undefined) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
searchParams.set(key, String(value));
|
|
196
|
+
}
|
|
197
|
+
const search = searchParams.toString();
|
|
198
|
+
return search.length > 0 ? `?${search}` : "";
|
|
199
|
+
}
|
|
186
200
|
async function request(baseUrl, path, init) {
|
|
187
201
|
try {
|
|
188
202
|
const response = await fetch(`${baseUrl}${path}`, init);
|
|
@@ -249,6 +263,19 @@ function postJson(baseUrl, path, body) {
|
|
|
249
263
|
}
|
|
250
264
|
function createClient(baseUrl) {
|
|
251
265
|
const normalizedBaseUrl = baseUrl.replace(/\/$/, "");
|
|
266
|
+
const toCreateMarketOrderRequest = (body) => ({
|
|
267
|
+
orderType: "market",
|
|
268
|
+
quoteId: body.id,
|
|
269
|
+
...body.senderAddress !== undefined ? { senderAddress: body.senderAddress } : {},
|
|
270
|
+
destinationAddress: body.destinationAddress,
|
|
271
|
+
refundAddress: body.refundAddress,
|
|
272
|
+
...body.integratorName !== undefined ? { integratorName: body.integratorName } : {},
|
|
273
|
+
...body.approvalMode !== undefined ? { approvalMode: body.approvalMode } : {}
|
|
274
|
+
});
|
|
275
|
+
const toCreateLimitOrderRequest = (body) => ({
|
|
276
|
+
orderType: "limit",
|
|
277
|
+
...body
|
|
278
|
+
});
|
|
252
279
|
const swap = (params) => {
|
|
253
280
|
const orderId = encodeURIComponent(params.orderId);
|
|
254
281
|
return {
|
|
@@ -267,19 +294,27 @@ function createClient(baseUrl) {
|
|
|
267
294
|
}
|
|
268
295
|
};
|
|
269
296
|
};
|
|
270
|
-
swap.post = (body) => postJson(normalizedBaseUrl, "/order
|
|
297
|
+
swap.post = (body) => postJson(normalizedBaseUrl, "/order", toCreateMarketOrderRequest(body));
|
|
271
298
|
const market = {
|
|
272
|
-
post: (body) => postJson(normalizedBaseUrl, "/order
|
|
299
|
+
post: (body) => postJson(normalizedBaseUrl, "/order", toCreateMarketOrderRequest(body))
|
|
273
300
|
};
|
|
274
301
|
const limit = {
|
|
275
|
-
post: (body) => postJson(normalizedBaseUrl, "/order
|
|
302
|
+
post: (body) => postJson(normalizedBaseUrl, "/order", toCreateLimitOrderRequest(body))
|
|
303
|
+
};
|
|
304
|
+
const liquidity = {
|
|
305
|
+
get: () => get(normalizedBaseUrl, "/liquidity")
|
|
306
|
+
};
|
|
307
|
+
const orders = {
|
|
308
|
+
get: (query) => get(normalizedBaseUrl, `/orders${buildQueryString(query)}`)
|
|
276
309
|
};
|
|
277
310
|
return {
|
|
311
|
+
liquidity,
|
|
278
312
|
quote: {
|
|
279
313
|
post: (body) => postJson(normalizedBaseUrl, "/quote", body)
|
|
280
314
|
},
|
|
281
315
|
market,
|
|
282
316
|
limit,
|
|
317
|
+
orders,
|
|
283
318
|
swap
|
|
284
319
|
};
|
|
285
320
|
}
|
|
@@ -358,45 +393,72 @@ class RiftSdk {
|
|
|
358
393
|
}
|
|
359
394
|
throw new SwapRouterApiError(message, status, value);
|
|
360
395
|
}
|
|
396
|
+
normalizeQuoteParameters(params) {
|
|
397
|
+
const legacy = params;
|
|
398
|
+
const fromAsset = params.fromAsset ?? legacy.from;
|
|
399
|
+
const toAsset = params.toAsset ?? legacy.to;
|
|
400
|
+
if (!fromAsset || !toAsset) {
|
|
401
|
+
throw new Error("Quote parameters must include fromAsset/toAsset or legacy from/to.");
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
...params,
|
|
405
|
+
fromAsset,
|
|
406
|
+
toAsset
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
normalizeLimitOrderOptions(options) {
|
|
410
|
+
const legacy = options;
|
|
411
|
+
const fromAsset = options.fromAsset ?? legacy.from;
|
|
412
|
+
const toAsset = options.toAsset ?? legacy.to;
|
|
413
|
+
if (!fromAsset || !toAsset) {
|
|
414
|
+
throw new Error("Limit order options must include fromAsset/toAsset or legacy from/to.");
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
...options,
|
|
418
|
+
fromAsset,
|
|
419
|
+
toAsset
|
|
420
|
+
};
|
|
421
|
+
}
|
|
361
422
|
async getQuote(params) {
|
|
423
|
+
params = this.normalizeQuoteParameters(params);
|
|
362
424
|
if (!Number.isFinite(params.slippageBps) || !Number.isInteger(params.slippageBps)) {
|
|
363
425
|
throw new Error("slippageBps must be an integer number of basis points");
|
|
364
426
|
}
|
|
365
427
|
if (params.slippageBps < 0 || params.slippageBps > 1e4) {
|
|
366
428
|
throw new Error("slippageBps must be between 0 and 10000");
|
|
367
429
|
}
|
|
368
|
-
const route = detectRoute(params.
|
|
430
|
+
const route = detectRoute(params.fromAsset, params.toAsset);
|
|
369
431
|
const quoteRequest = {
|
|
370
432
|
type: params.mode === "exact_input" ? "EXACT_INPUT" : "EXACT_OUTPUT",
|
|
371
|
-
|
|
372
|
-
|
|
433
|
+
fromAsset: params.fromAsset,
|
|
434
|
+
toAsset: params.toAsset,
|
|
373
435
|
amount: params.amount,
|
|
374
436
|
slippageBps: params.slippageBps
|
|
375
437
|
};
|
|
376
438
|
const riftQuote = this.unwrapEdenResult(await this.riftClient.quote.post(quoteRequest));
|
|
377
439
|
const quote = this.buildQuoteResult(riftQuote, params);
|
|
378
|
-
const isChained = route.type === "direct_rift" && route.direction === "from_btc" && !isCbBtc(params.
|
|
440
|
+
const isChained = route.type === "direct_rift" && route.direction === "from_btc" && !isCbBtc(params.toAsset);
|
|
379
441
|
return {
|
|
380
442
|
quote,
|
|
381
443
|
executeSwap: async (context) => {
|
|
382
444
|
if (!context?.destinationAddress) {
|
|
383
445
|
throw new Error("destinationAddress is required to execute swap");
|
|
384
446
|
}
|
|
385
|
-
if (params.
|
|
447
|
+
if (params.fromAsset.chain.kind === "BITCOIN" && !context.refundAddress) {
|
|
386
448
|
throw new Error("refundAddress is required for BTC swaps (Bitcoin refund address)");
|
|
387
449
|
}
|
|
388
450
|
this.logDebug("executeSwap called", {
|
|
389
451
|
route: route.type,
|
|
390
452
|
mode: params.mode,
|
|
391
|
-
|
|
392
|
-
|
|
453
|
+
fromAsset: params.fromAsset,
|
|
454
|
+
toAsset: params.toAsset,
|
|
393
455
|
amount: params.amount
|
|
394
456
|
});
|
|
395
457
|
const refundAddress = context.refundAddress ?? this.getRefundAddress(params, context);
|
|
396
458
|
this.logDebug("resolved refund address", { refundAddress });
|
|
397
459
|
if (this.preflightCheckBalances) {
|
|
398
460
|
this.logDebug("running preflight balance check");
|
|
399
|
-
await this.assertSufficientBalance(params.
|
|
461
|
+
await this.assertSufficientBalance(params.fromAsset, quote.fromAsset.expected, context);
|
|
400
462
|
}
|
|
401
463
|
return this.executeOrderFlow({
|
|
402
464
|
context,
|
|
@@ -404,7 +466,7 @@ class RiftSdk {
|
|
|
404
466
|
chained: isChained,
|
|
405
467
|
createOrder: async () => {
|
|
406
468
|
this.logDebug("creating market order", { quoteId: riftQuote.id });
|
|
407
|
-
const senderAddress = params.
|
|
469
|
+
const senderAddress = params.fromAsset.chain.kind === "EVM" ? this.getAddress(context) : undefined;
|
|
408
470
|
return this.unwrapEdenResult(await this.riftClient.market.post({
|
|
409
471
|
id: riftQuote.id,
|
|
410
472
|
...senderAddress ? { senderAddress } : {},
|
|
@@ -419,15 +481,16 @@ class RiftSdk {
|
|
|
419
481
|
};
|
|
420
482
|
}
|
|
421
483
|
async createLimitOrder(options) {
|
|
484
|
+
options = this.normalizeLimitOrderOptions(options);
|
|
422
485
|
if (!options?.destinationAddress) {
|
|
423
486
|
throw new Error("destinationAddress is required to create a limit order");
|
|
424
487
|
}
|
|
425
|
-
if (options.
|
|
426
|
-
if (!isAddress(options.
|
|
488
|
+
if (options.fromAsset.token.kind === "TOKEN") {
|
|
489
|
+
if (!isAddress(options.fromAsset.token.address)) {
|
|
427
490
|
throw new Error("from.token.address must be a valid EVM token address");
|
|
428
491
|
}
|
|
429
492
|
}
|
|
430
|
-
if (options.
|
|
493
|
+
if (options.toAsset.token.kind === "TOKEN" && !isAddress(options.toAsset.token.address)) {
|
|
431
494
|
throw new Error("to.token.address must be a valid EVM token address");
|
|
432
495
|
}
|
|
433
496
|
this.assertPositiveIntegerString(options.pricing.buyAmount, "pricing.buyAmount");
|
|
@@ -437,14 +500,14 @@ class RiftSdk {
|
|
|
437
500
|
}
|
|
438
501
|
let refundAddress;
|
|
439
502
|
let senderAddress;
|
|
440
|
-
if (options.
|
|
441
|
-
if (options.
|
|
503
|
+
if (options.fromAsset.chain.kind === "BITCOIN") {
|
|
504
|
+
if (options.fromAsset.token.kind !== "NATIVE") {
|
|
442
505
|
throw new Error("BTC-start limit orders must use native BTC as the input");
|
|
443
506
|
}
|
|
444
507
|
if (!options.refundAddress) {
|
|
445
508
|
throw new Error("refundAddress is required for BTC-start limit orders (Bitcoin refund address).");
|
|
446
509
|
}
|
|
447
|
-
if (isCbBtc(options.
|
|
510
|
+
if (isCbBtc(options.toAsset)) {
|
|
448
511
|
throw new Error("BTC -> cbBTC limit orders are not supported");
|
|
449
512
|
}
|
|
450
513
|
refundAddress = options.refundAddress;
|
|
@@ -455,31 +518,31 @@ class RiftSdk {
|
|
|
455
518
|
throw new Error("refundAddress must be a valid EVM address for EVM-start limit orders");
|
|
456
519
|
}
|
|
457
520
|
}
|
|
458
|
-
if (options.
|
|
459
|
-
if (options.
|
|
521
|
+
if (options.toAsset.chain.kind === "BITCOIN") {
|
|
522
|
+
if (options.fromAsset.chain.kind !== "EVM") {
|
|
460
523
|
throw new Error("Bitcoin-payout limit orders require an EVM source currency.");
|
|
461
524
|
}
|
|
462
|
-
if (isCbBtc(options.
|
|
525
|
+
if (isCbBtc(options.fromAsset)) {
|
|
463
526
|
throw new Error("cbBTC -> BTC limit orders are not supported");
|
|
464
527
|
}
|
|
465
528
|
} else {
|
|
466
529
|
if (!isAddress(options.destinationAddress)) {
|
|
467
530
|
throw new Error("destinationAddress must be a valid EVM address for EVM-destination limit orders");
|
|
468
531
|
}
|
|
469
|
-
if (options.
|
|
470
|
-
throw new Error(`Unsupported limit order chainId: ${options.
|
|
532
|
+
if (options.toAsset.chain.chainId !== 1 && options.toAsset.chain.chainId !== 8453) {
|
|
533
|
+
throw new Error(`Unsupported limit order chainId: ${options.toAsset.chain.chainId}. Expected 1 or 8453.`);
|
|
471
534
|
}
|
|
472
|
-
if (options.
|
|
473
|
-
if (options.
|
|
535
|
+
if (options.fromAsset.chain.kind === "EVM") {
|
|
536
|
+
if (options.fromAsset.chain.chainId !== options.toAsset.chain.chainId) {
|
|
474
537
|
throw new Error("EVM-start limit orders currently require from/to on the same EVM chain.");
|
|
475
538
|
}
|
|
476
539
|
}
|
|
477
540
|
}
|
|
478
541
|
this.logDebug("resolved limit order refund address", { refundAddress });
|
|
479
|
-
const route = detectRoute(options.
|
|
480
|
-
if (this.preflightCheckBalances && options.
|
|
542
|
+
const route = detectRoute(options.fromAsset, options.toAsset);
|
|
543
|
+
if (this.preflightCheckBalances && options.fromAsset.chain.kind === "EVM") {
|
|
481
544
|
this.logDebug("running limit-order preflight balance check");
|
|
482
|
-
await this.assertSufficientBalance(options.
|
|
545
|
+
await this.assertSufficientBalance(options.fromAsset, options.pricing.sellAmount, options);
|
|
483
546
|
}
|
|
484
547
|
return this.executeOrderFlow({
|
|
485
548
|
context: options,
|
|
@@ -487,8 +550,8 @@ class RiftSdk {
|
|
|
487
550
|
chained: false,
|
|
488
551
|
createOrder: async () => {
|
|
489
552
|
const request2 = {
|
|
490
|
-
|
|
491
|
-
|
|
553
|
+
fromAsset: options.fromAsset,
|
|
554
|
+
toAsset: options.toAsset,
|
|
492
555
|
...senderAddress ? { senderAddress } : {},
|
|
493
556
|
pricing: options.pricing,
|
|
494
557
|
destinationAddress: options.destinationAddress,
|
|
@@ -498,7 +561,7 @@ class RiftSdk {
|
|
|
498
561
|
integratorName: this.integratorName
|
|
499
562
|
};
|
|
500
563
|
this.logDebug("creating limit order", {
|
|
501
|
-
|
|
564
|
+
toAsset: request2.toAsset,
|
|
502
565
|
pricing: request2.pricing
|
|
503
566
|
});
|
|
504
567
|
return this.unwrapEdenResult(await this.riftClient.limit.post(request2));
|
|
@@ -815,8 +878,10 @@ class RiftSdk {
|
|
|
815
878
|
return {
|
|
816
879
|
mode: "exact_input",
|
|
817
880
|
quoteId: riftQuote.id,
|
|
818
|
-
|
|
819
|
-
|
|
881
|
+
fromAsset: riftQuote.fromAsset,
|
|
882
|
+
from: riftQuote.fromAsset,
|
|
883
|
+
toAsset: riftQuote.toAsset,
|
|
884
|
+
to: riftQuote.toAsset,
|
|
820
885
|
fees: riftQuote.fees,
|
|
821
886
|
expiresAt: new Date(riftQuote.expiresAt)
|
|
822
887
|
};
|
|
@@ -824,8 +889,10 @@ class RiftSdk {
|
|
|
824
889
|
return {
|
|
825
890
|
mode: "exact_output",
|
|
826
891
|
quoteId: riftQuote.id,
|
|
827
|
-
|
|
828
|
-
|
|
892
|
+
fromAsset: riftQuote.fromAsset,
|
|
893
|
+
from: riftQuote.fromAsset,
|
|
894
|
+
toAsset: riftQuote.toAsset,
|
|
895
|
+
to: riftQuote.toAsset,
|
|
829
896
|
fees: riftQuote.fees,
|
|
830
897
|
expiresAt: new Date(riftQuote.expiresAt)
|
|
831
898
|
};
|
|
@@ -941,7 +1008,7 @@ class RiftSdk {
|
|
|
941
1008
|
return account.address;
|
|
942
1009
|
}
|
|
943
1010
|
getRefundAddress(params, context) {
|
|
944
|
-
if (params.
|
|
1011
|
+
if (params.fromAsset.chain.kind === "BITCOIN") {
|
|
945
1012
|
throw new Error("refundAddress is required for BTC swaps (Bitcoin refund address)");
|
|
946
1013
|
}
|
|
947
1014
|
return this.getAddress(context);
|
|
@@ -995,9 +1062,18 @@ class RiftSdk {
|
|
|
995
1062
|
}
|
|
996
1063
|
return context.sendBitcoin;
|
|
997
1064
|
}
|
|
998
|
-
async
|
|
1065
|
+
async getOrderStatus(orderId) {
|
|
999
1066
|
return this.unwrapEdenResult(await this.riftClient.swap({ orderId }).get());
|
|
1000
1067
|
}
|
|
1068
|
+
async getSwapStatus(orderId) {
|
|
1069
|
+
return this.getOrderStatus(orderId);
|
|
1070
|
+
}
|
|
1071
|
+
async getOrders(options) {
|
|
1072
|
+
return this.unwrapEdenResult(await this.riftClient.orders.get(options));
|
|
1073
|
+
}
|
|
1074
|
+
async getLiquidity() {
|
|
1075
|
+
return this.unwrapEdenResult(await this.riftClient.liquidity.get());
|
|
1076
|
+
}
|
|
1001
1077
|
async cancelOrder(options) {
|
|
1002
1078
|
const walletClient = options.walletClient;
|
|
1003
1079
|
const account = walletClient.account;
|