@riftresearch/sdk 0.13.0 → 0.14.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 +13 -0
- package/dist/index.d.ts +32 -1
- package/dist/index.js +73 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,3 +101,16 @@ const result = await sdk.createLimitOrder({
|
|
|
101
101
|
console.log(`Order ID: ${result.swapId}`)
|
|
102
102
|
console.log(`Status: ${result.status}`)
|
|
103
103
|
```
|
|
104
|
+
|
|
105
|
+
For supported limit orders, you can later cancel the order. The SDK will fetch the
|
|
106
|
+
correct typed-data payload from the router, sign it with your wallet, and submit the
|
|
107
|
+
cancellation:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const cancel = await sdk.cancelOrder({
|
|
111
|
+
swapId: result.swapId,
|
|
112
|
+
walletClient,
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
console.log(`Cancel accepted: ${cancel.accepted}`)
|
|
116
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -241,6 +241,14 @@ interface SwapResponse {
|
|
|
241
241
|
/** Ordered list of steps the client must execute */
|
|
242
242
|
executionSteps: ExecutionStep[];
|
|
243
243
|
}
|
|
244
|
+
interface CancelOrderResponse {
|
|
245
|
+
/** The public swap ID from the router API. */
|
|
246
|
+
swapId: string;
|
|
247
|
+
/** Whether the downstream cancellation request was accepted. */
|
|
248
|
+
accepted: boolean;
|
|
249
|
+
/** Optional downstream CoW order UID for the cancelled order. */
|
|
250
|
+
cowOrderUid?: string;
|
|
251
|
+
}
|
|
244
252
|
/** Create an ERC-20 currency on an EVM chain */
|
|
245
253
|
declare function createCurrency(params: {
|
|
246
254
|
chainId: number;
|
|
@@ -383,6 +391,7 @@ interface SwapResult {
|
|
|
383
391
|
status: SwapStatus;
|
|
384
392
|
rift: RiftSwap;
|
|
385
393
|
}
|
|
394
|
+
type CancelOrderResult = CancelOrderResponse;
|
|
386
395
|
/**
|
|
387
396
|
* Function type for sending Bitcoin.
|
|
388
397
|
* Implementers provide this function to handle BTC transactions in their app.
|
|
@@ -440,6 +449,17 @@ type ExecuteSwapOptions<chain extends Chain2 | undefined = Chain2 | undefined> =
|
|
|
440
449
|
/** Address to receive refunds if swap fails. Defaults to source wallet address */
|
|
441
450
|
refundAddress?: string;
|
|
442
451
|
};
|
|
452
|
+
type CancelOrderOptions<chain extends Chain2 | undefined = Chain2 | undefined> = {
|
|
453
|
+
swapId: string;
|
|
454
|
+
/** Viem WalletClient for signing the router-prepared cancellation typed data */
|
|
455
|
+
walletClient: WalletClient<Transport, chain, Account | undefined>;
|
|
456
|
+
/**
|
|
457
|
+
* Optional absolute Unix timestamp in UTC seconds for tee-swapper
|
|
458
|
+
* cancellation signatures. Defaults to now + 5 minutes and is ignored for
|
|
459
|
+
* direct CoW-backed cancellations.
|
|
460
|
+
*/
|
|
461
|
+
deadline?: number;
|
|
462
|
+
};
|
|
443
463
|
interface RiftSdkOptions {
|
|
444
464
|
/** Rift API URL. Defaults to production API */
|
|
445
465
|
apiUrl?: string;
|
|
@@ -485,6 +505,9 @@ declare class RiftSdk {
|
|
|
485
505
|
createLimitOrder<chain extends Chain3 | undefined = Chain3 | undefined>(options: CreateLimitOrderOptions<chain>): Promise<SwapResult>;
|
|
486
506
|
private assertPositiveIntegerString;
|
|
487
507
|
private assertValidLimitValidUntil;
|
|
508
|
+
private assertValidCancelDeadline;
|
|
509
|
+
private assertCancelWalletChain;
|
|
510
|
+
private signPreparedCancellation;
|
|
488
511
|
private executeOrderFlow;
|
|
489
512
|
/**
|
|
490
513
|
* Execute a single step from the server's execution steps.
|
|
@@ -519,6 +542,14 @@ declare class RiftSdk {
|
|
|
519
542
|
* Get the current status of a swap by its ID.
|
|
520
543
|
*/
|
|
521
544
|
getSwapStatus(swapId: string): Promise<SwapStatusResponse>;
|
|
545
|
+
/**
|
|
546
|
+
* Cancel a supported limit order through the swap router.
|
|
547
|
+
*
|
|
548
|
+
* The SDK first requests the backend-specific typed-data payload from the
|
|
549
|
+
* router, signs it with the provided wallet, and then submits the signed
|
|
550
|
+
* cancellation request back to the router.
|
|
551
|
+
*/
|
|
552
|
+
cancelOrder<chain extends Chain3 | undefined = Chain3 | undefined>(options: CancelOrderOptions<chain>): Promise<CancelOrderResult>;
|
|
522
553
|
}
|
|
523
554
|
declare function createRiftSdk(options: RiftSdkOptions): RiftSdk;
|
|
524
|
-
export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, 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, BtcTransferStep, BtcTransferKind, BitcoinChain };
|
|
555
|
+
export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, TokenIdentifier, 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 };
|
package/dist/index.js
CHANGED
|
@@ -226,6 +226,12 @@ function createClient(baseUrl) {
|
|
|
226
226
|
const swapId = encodeURIComponent(params.swapId);
|
|
227
227
|
return {
|
|
228
228
|
get: () => get(normalizedBaseUrl, `/order/${swapId}`),
|
|
229
|
+
cancel: {
|
|
230
|
+
prepare: {
|
|
231
|
+
post: (body) => postJson(normalizedBaseUrl, `/order/${swapId}/cancel/prepare`, body)
|
|
232
|
+
},
|
|
233
|
+
post: (body) => postJson(normalizedBaseUrl, `/order/${swapId}/cancel`, body)
|
|
234
|
+
},
|
|
229
235
|
tx: {
|
|
230
236
|
post: (body) => postJson(normalizedBaseUrl, `/order/${swapId}/tx`, body)
|
|
231
237
|
},
|
|
@@ -259,6 +265,7 @@ var DEFAULT_LIMIT_VALIDITY_WINDOW_SECONDS = 365 * 24 * 60 * 60;
|
|
|
259
265
|
var MIN_LIMIT_VALIDITY_LEAD_TIME_SECONDS = 60;
|
|
260
266
|
var MAX_LIMIT_VALIDITY_WINDOW_SECONDS = DEFAULT_LIMIT_VALIDITY_WINDOW_SECONDS;
|
|
261
267
|
var MAX_COW_VALID_TO = 4294967295;
|
|
268
|
+
var CANCEL_AUTH_WINDOW_SECONDS = 300;
|
|
262
269
|
|
|
263
270
|
class RiftSdk {
|
|
264
271
|
riftClient;
|
|
@@ -467,6 +474,51 @@ class RiftSdk {
|
|
|
467
474
|
throw new Error(`${field} must be between 60 seconds and 31536000 seconds in the future`);
|
|
468
475
|
}
|
|
469
476
|
}
|
|
477
|
+
assertValidCancelDeadline(deadline) {
|
|
478
|
+
if (!Number.isInteger(deadline)) {
|
|
479
|
+
throw new Error("deadline must be an integer when provided");
|
|
480
|
+
}
|
|
481
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
482
|
+
if (deadline < nowSeconds) {
|
|
483
|
+
throw new Error("deadline must be in the future");
|
|
484
|
+
}
|
|
485
|
+
if (deadline > nowSeconds + CANCEL_AUTH_WINDOW_SECONDS) {
|
|
486
|
+
throw new Error(`deadline must be within ${CANCEL_AUTH_WINDOW_SECONDS} seconds`);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
assertCancelWalletChain(walletClient, chainId) {
|
|
490
|
+
const walletChainId = walletClient.chain?.id;
|
|
491
|
+
if (!walletChainId) {
|
|
492
|
+
throw new Error("Wallet client is missing an EVM chain configuration");
|
|
493
|
+
}
|
|
494
|
+
if (walletChainId !== chainId) {
|
|
495
|
+
throw new Error(`Wallet client chain mismatch. Expected ${chainId}, got ${walletChainId}`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
async signPreparedCancellation(walletClient, account, preparation) {
|
|
499
|
+
if (preparation.kind === "tee_swapper") {
|
|
500
|
+
return walletClient.signTypedData({
|
|
501
|
+
account,
|
|
502
|
+
domain: preparation.typedData.domain,
|
|
503
|
+
types: preparation.typedData.types,
|
|
504
|
+
primaryType: preparation.typedData.primaryType,
|
|
505
|
+
message: {
|
|
506
|
+
swapId: preparation.typedData.message.swapId,
|
|
507
|
+
deadline: BigInt(preparation.typedData.message.deadline)
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
return walletClient.signTypedData({
|
|
512
|
+
account,
|
|
513
|
+
domain: {
|
|
514
|
+
...preparation.typedData.domain,
|
|
515
|
+
verifyingContract: preparation.typedData.domain.verifyingContract
|
|
516
|
+
},
|
|
517
|
+
types: preparation.typedData.types,
|
|
518
|
+
primaryType: preparation.typedData.primaryType,
|
|
519
|
+
message: preparation.typedData.message
|
|
520
|
+
});
|
|
521
|
+
}
|
|
470
522
|
async executeOrderFlow(params) {
|
|
471
523
|
const swapResponse = await params.createOrder();
|
|
472
524
|
this.logDebug("order created", {
|
|
@@ -847,6 +899,27 @@ class RiftSdk {
|
|
|
847
899
|
async getSwapStatus(swapId) {
|
|
848
900
|
return this.unwrapEdenResult(await this.riftClient.swap({ swapId }).get());
|
|
849
901
|
}
|
|
902
|
+
async cancelOrder(options) {
|
|
903
|
+
const walletClient = options.walletClient;
|
|
904
|
+
const account = walletClient.account;
|
|
905
|
+
if (!account) {
|
|
906
|
+
throw new Error("No account configured on wallet client");
|
|
907
|
+
}
|
|
908
|
+
const deadline = options.deadline ?? Math.floor(Date.now() / 1000) + CANCEL_AUTH_WINDOW_SECONDS;
|
|
909
|
+
this.assertValidCancelDeadline(deadline);
|
|
910
|
+
const preparation = this.unwrapEdenResult(await this.riftClient.swap({ swapId: options.swapId }).cancel.prepare.post({
|
|
911
|
+
deadline
|
|
912
|
+
}));
|
|
913
|
+
this.assertCancelWalletChain(walletClient, preparation.cancellation.chainId);
|
|
914
|
+
const signature = await this.signPreparedCancellation(walletClient, account, preparation.cancellation);
|
|
915
|
+
const request2 = {
|
|
916
|
+
authorization: {
|
|
917
|
+
signature,
|
|
918
|
+
...preparation.cancellation.kind === "tee_swapper" ? { deadline: preparation.cancellation.deadline } : {}
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
return this.unwrapEdenResult(await this.riftClient.swap({ swapId: options.swapId }).cancel.post(request2));
|
|
922
|
+
}
|
|
850
923
|
}
|
|
851
924
|
function createRiftSdk(options) {
|
|
852
925
|
return new RiftSdk(options);
|