@shogun-sdk/intents-sdk 1.1.1 → 1.2.1
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/esm/constants.js +24 -8
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/core/evm/intent-provider.js +55 -2
- package/dist/esm/core/evm/intent-provider.js.map +1 -1
- package/dist/esm/core/evm/order-signature.js +12 -1
- package/dist/esm/core/evm/order-signature.js.map +1 -1
- package/dist/esm/core/evm/permit2.js +24 -1
- package/dist/esm/core/evm/permit2.js.map +1 -1
- package/dist/esm/core/evm/sdk.js +9 -4
- package/dist/esm/core/evm/sdk.js.map +1 -1
- package/dist/esm/core/evm/validator.js +21 -0
- package/dist/esm/core/evm/validator.js.map +1 -1
- package/dist/esm/core/orders/cross-chain.js +4 -1
- package/dist/esm/core/orders/cross-chain.js.map +1 -1
- package/dist/esm/core/orders/dca-single-chain.js +169 -0
- package/dist/esm/core/orders/dca-single-chain.js.map +1 -0
- package/dist/esm/core/orders/single-chain.js +6 -1
- package/dist/esm/core/orders/single-chain.js.map +1 -1
- package/dist/esm/core/sdk.js +55 -81
- package/dist/esm/core/sdk.js.map +1 -1
- package/dist/esm/core/solana/dca/cancel-order.js +61 -0
- package/dist/esm/core/solana/dca/cancel-order.js.map +1 -0
- package/dist/esm/core/solana/dca/create-order.js +82 -0
- package/dist/esm/core/solana/dca/create-order.js.map +1 -0
- package/dist/esm/core/solana/generated/cross-chain/errors/sourceChainGuard.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/cancelOrder.js +5 -20
- package/dist/esm/core/solana/generated/cross-chain/instructions/cancelOrder.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/claimTokens.js +4 -16
- package/dist/esm/core/solana/generated/cross-chain/instructions/claimTokens.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/collectProtocolFees.js +4 -16
- package/dist/esm/core/solana/generated/cross-chain/instructions/collectProtocolFees.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/createGuard.js +14 -56
- package/dist/esm/core/solana/generated/cross-chain/instructions/createGuard.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/createOrder.js +6 -24
- package/dist/esm/core/solana/generated/cross-chain/instructions/createOrder.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/preStartOrderExecution.js +4 -16
- package/dist/esm/core/solana/generated/cross-chain/instructions/preStartOrderExecution.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/setAdmin.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/setAuctioneerPubKey.js +1 -4
- package/dist/esm/core/solana/generated/cross-chain/instructions/setAuctioneerPubKey.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/startOrderExecution.js +2 -8
- package/dist/esm/core/solana/generated/cross-chain/instructions/startOrderExecution.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/instructions/startOrderExecutionAfterSwap.js +3 -12
- package/dist/esm/core/solana/generated/cross-chain/instructions/startOrderExecutionAfterSwap.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/shared/index.js +2 -5
- package/dist/esm/core/solana/generated/cross-chain/shared/index.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/types/auctioneerPubkeyUpdated.js.map +1 -1
- package/dist/esm/core/solana/generated/cross-chain/types/tokenInSwapped.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/errors/singleChainGuard.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/cancelDcaOrder.js +2 -8
- package/dist/esm/core/solana/generated/single-chain/instructions/cancelDcaOrder.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/cancelLimitOrder.js +2 -8
- package/dist/esm/core/solana/generated/single-chain/instructions/cancelLimitOrder.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/collectProtocolFees.js +6 -24
- package/dist/esm/core/solana/generated/single-chain/instructions/collectProtocolFees.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/createDcaOrder.js +6 -24
- package/dist/esm/core/solana/generated/single-chain/instructions/createDcaOrder.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/createGuard.js +4 -16
- package/dist/esm/core/solana/generated/single-chain/instructions/createGuard.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/createLimitOrder.js +6 -24
- package/dist/esm/core/solana/generated/single-chain/instructions/createLimitOrder.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/fulfillDcaOrderInterval.js +9 -36
- package/dist/esm/core/solana/generated/single-chain/instructions/fulfillDcaOrderInterval.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/fulfillLimitOrder.js +8 -32
- package/dist/esm/core/solana/generated/single-chain/instructions/fulfillLimitOrder.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/setAdmin.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/instructions/setAuctioneerPubKey.js +1 -4
- package/dist/esm/core/solana/generated/single-chain/instructions/setAuctioneerPubKey.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/shared/index.js +2 -5
- package/dist/esm/core/solana/generated/single-chain/shared/index.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/types/auctioneerPubkeyUpdated.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/types/guardCreated.js.map +1 -1
- package/dist/esm/core/solana/generated/single-chain/types/limitOrderFulfilled.js.map +1 -1
- package/dist/esm/core/solana/inspect.js +43 -0
- package/dist/esm/core/solana/inspect.js.map +1 -0
- package/dist/esm/core/solana/sdk.js +36 -0
- package/dist/esm/core/solana/sdk.js.map +1 -1
- package/dist/esm/core/solana/utils.js.map +1 -1
- package/dist/esm/core/solana/validator.js +3 -0
- package/dist/esm/core/solana/validator.js.map +1 -1
- package/dist/esm/core/sui/sdk.js +0 -3
- package/dist/esm/core/sui/sdk.js.map +1 -1
- package/dist/esm/core/sui/validator.js +4 -0
- package/dist/esm/core/sui/validator.js.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/base-validator.js +28 -0
- package/dist/esm/utils/base-validator.js.map +1 -1
- package/dist/esm/utils/order-validator.js +31 -0
- package/dist/esm/utils/order-validator.js.map +1 -1
- package/dist/esm/utils/quote/aggregator.js +2 -2
- package/dist/esm/utils/quote/aggregator.js.map +1 -1
- package/dist/esm/utils/quote/liquidswap.js.map +1 -1
- package/dist/types/constants.d.ts +10 -7
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/core/evm/intent-provider.d.ts +5 -2
- package/dist/types/core/evm/intent-provider.d.ts.map +1 -1
- package/dist/types/core/evm/order-signature.d.ts +5 -0
- package/dist/types/core/evm/order-signature.d.ts.map +1 -1
- package/dist/types/core/evm/permit2.d.ts +90 -0
- package/dist/types/core/evm/permit2.d.ts.map +1 -1
- package/dist/types/core/evm/sdk.d.ts +3 -1
- package/dist/types/core/evm/sdk.d.ts.map +1 -1
- package/dist/types/core/evm/validator.d.ts +4 -0
- package/dist/types/core/evm/validator.d.ts.map +1 -1
- package/dist/types/core/orders/cross-chain.d.ts.map +1 -1
- package/dist/types/core/orders/dca-single-chain.d.ts +47 -0
- package/dist/types/core/orders/dca-single-chain.d.ts.map +1 -0
- package/dist/types/core/orders/single-chain.d.ts.map +1 -1
- package/dist/types/core/sdk.d.ts +15 -10
- package/dist/types/core/sdk.d.ts.map +1 -1
- package/dist/types/core/solana/dca/cancel-order.d.ts +5 -0
- package/dist/types/core/solana/dca/cancel-order.d.ts.map +1 -0
- package/dist/types/core/solana/dca/create-order.d.ts +8 -0
- package/dist/types/core/solana/dca/create-order.d.ts.map +1 -0
- package/dist/types/core/solana/generated/cross-chain/errors/sourceChainGuard.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/acceptAdmin.d.ts +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/acceptAdmin.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/cancelOrder.d.ts +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/cancelOrder.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/claimTokens.d.ts +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/claimTokens.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/collectProtocolFees.d.ts +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/collectProtocolFees.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/createGuard.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/createOrder.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/initialize.d.ts +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/initialize.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/preStartOrderExecution.d.ts +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/preStartOrderExecution.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/setAdmin.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/setAuctioneerPubKey.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/startOrderExecution.d.ts +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/startOrderExecution.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/instructions/startOrderExecutionAfterSwap.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/shared/index.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/types/auctioneerPubkeyUpdated.d.ts.map +1 -1
- package/dist/types/core/solana/generated/cross-chain/types/tokenInSwapped.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/errors/singleChainGuard.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/acceptAdmin.d.ts +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/acceptAdmin.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/cancelDcaOrder.d.ts +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/cancelDcaOrder.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/cancelLimitOrder.d.ts +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/cancelLimitOrder.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/collectProtocolFees.d.ts +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/collectProtocolFees.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/createDcaOrder.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/createGuard.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/createLimitOrder.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/fulfillDcaOrderInterval.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/fulfillLimitOrder.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/initialize.d.ts +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/initialize.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/setAdmin.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/instructions/setAuctioneerPubKey.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/shared/index.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/types/auctioneerPubkeyUpdated.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/types/guardCreated.d.ts.map +1 -1
- package/dist/types/core/solana/generated/single-chain/types/limitOrderFulfilled.d.ts.map +1 -1
- package/dist/types/core/solana/inspect.d.ts +14 -0
- package/dist/types/core/solana/inspect.d.ts.map +1 -0
- package/dist/types/core/solana/sdk.d.ts +4 -1
- package/dist/types/core/solana/sdk.d.ts.map +1 -1
- package/dist/types/core/solana/utils.d.ts +2 -1
- package/dist/types/core/solana/utils.d.ts.map +1 -1
- package/dist/types/core/solana/validator.d.ts +1 -0
- package/dist/types/core/solana/validator.d.ts.map +1 -1
- package/dist/types/core/sui/sdk.d.ts +1 -2
- package/dist/types/core/sui/sdk.d.ts.map +1 -1
- package/dist/types/core/sui/validator.d.ts +1 -0
- package/dist/types/core/sui/validator.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types/intent.d.ts +22 -0
- package/dist/types/types/intent.d.ts.map +1 -1
- package/dist/types/utils/base-validator.d.ts +7 -0
- package/dist/types/utils/base-validator.d.ts.map +1 -1
- package/dist/types/utils/order-validator.d.ts +15 -0
- package/dist/types/utils/order-validator.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth/siwe.ts +1 -1
- package/src/constants.ts +72 -39
- package/src/core/evm/connectors/hyperevm.ts +1 -1
- package/src/core/evm/intent-provider.ts +88 -4
- package/src/core/evm/order-signature.ts +23 -1
- package/src/core/evm/permit2.ts +47 -1
- package/src/core/evm/sdk.ts +20 -7
- package/src/core/evm/validator.ts +32 -0
- package/src/core/orders/api/fetch.ts +0 -1
- package/src/core/orders/api/index.ts +4 -4
- package/src/core/orders/cross-chain.ts +5 -1
- package/src/core/orders/dca-single-chain.ts +143 -0
- package/src/core/orders/single-chain.ts +8 -1
- package/src/core/sdk.ts +72 -100
- package/src/core/solana/cancel-order.ts +1 -1
- package/src/core/solana/dca/cancel-order.ts +91 -0
- package/src/core/solana/dca/create-order.ts +142 -0
- package/src/core/solana/generated/cross-chain/errors/sourceChainGuard.ts +1 -3
- package/src/core/solana/generated/cross-chain/instructions/acceptAdmin.ts +1 -1
- package/src/core/solana/generated/cross-chain/instructions/cancelOrder.ts +6 -21
- package/src/core/solana/generated/cross-chain/instructions/claimTokens.ts +5 -17
- package/src/core/solana/generated/cross-chain/instructions/collectProtocolFees.ts +6 -20
- package/src/core/solana/generated/cross-chain/instructions/createGuard.ts +14 -56
- package/src/core/solana/generated/cross-chain/instructions/createOrder.ts +6 -24
- package/src/core/solana/generated/cross-chain/instructions/initialize.ts +1 -1
- package/src/core/solana/generated/cross-chain/instructions/preStartOrderExecution.ts +6 -20
- package/src/core/solana/generated/cross-chain/instructions/setAdmin.ts +1 -4
- package/src/core/solana/generated/cross-chain/instructions/setAuctioneerPubKey.ts +2 -7
- package/src/core/solana/generated/cross-chain/instructions/startOrderExecution.ts +4 -12
- package/src/core/solana/generated/cross-chain/instructions/startOrderExecutionAfterSwap.ts +3 -12
- package/src/core/solana/generated/cross-chain/shared/index.ts +2 -5
- package/src/core/solana/generated/cross-chain/types/auctioneerPubkeyUpdated.ts +1 -4
- package/src/core/solana/generated/cross-chain/types/tokenInSwapped.ts +1 -5
- package/src/core/solana/generated/single-chain/errors/singleChainGuard.ts +1 -3
- package/src/core/solana/generated/single-chain/instructions/acceptAdmin.ts +1 -1
- package/src/core/solana/generated/single-chain/instructions/cancelDcaOrder.ts +4 -12
- package/src/core/solana/generated/single-chain/instructions/cancelLimitOrder.ts +4 -12
- package/src/core/solana/generated/single-chain/instructions/collectProtocolFees.ts +8 -28
- package/src/core/solana/generated/single-chain/instructions/createDcaOrder.ts +6 -24
- package/src/core/solana/generated/single-chain/instructions/createGuard.ts +5 -20
- package/src/core/solana/generated/single-chain/instructions/createLimitOrder.ts +6 -24
- package/src/core/solana/generated/single-chain/instructions/fulfillDcaOrderInterval.ts +9 -36
- package/src/core/solana/generated/single-chain/instructions/fulfillLimitOrder.ts +8 -32
- package/src/core/solana/generated/single-chain/instructions/initialize.ts +1 -1
- package/src/core/solana/generated/single-chain/instructions/setAdmin.ts +1 -4
- package/src/core/solana/generated/single-chain/instructions/setAuctioneerPubKey.ts +2 -7
- package/src/core/solana/generated/single-chain/shared/index.ts +2 -5
- package/src/core/solana/generated/single-chain/types/auctioneerPubkeyUpdated.ts +1 -4
- package/src/core/solana/generated/single-chain/types/guardCreated.ts +1 -5
- package/src/core/solana/generated/single-chain/types/limitOrderFulfilled.ts +1 -4
- package/src/core/solana/inspect.ts +50 -0
- package/src/core/solana/order-instructions.ts +1 -1
- package/src/core/solana/sdk.ts +65 -2
- package/src/core/solana/utils.ts +2 -1
- package/src/core/solana/validator.ts +4 -0
- package/src/core/sui/sdk.ts +2 -6
- package/src/core/sui/validator.ts +5 -0
- package/src/index.ts +12 -1
- package/src/types/api.ts +1 -1
- package/src/types/intent.ts +27 -0
- package/src/utils/base-validator.ts +40 -0
- package/src/utils/order-validator.ts +38 -0
- package/src/utils/quote/aggregator.ts +2 -2
- package/src/utils/quote/liquidswap.ts +2 -2
|
@@ -3,15 +3,15 @@ import type { ApiResponse, ApiUserOrders } from '../../../types/api.js';
|
|
|
3
3
|
|
|
4
4
|
export class AuctioneerAPI {
|
|
5
5
|
public aggregatedToken: string;
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
constructor(aggregatedToken: string) {
|
|
8
8
|
this.aggregatedToken = aggregatedToken;
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
public extend(token: string) {
|
|
12
12
|
this.aggregatedToken = token;
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
public async getUserOrders() {
|
|
16
16
|
const url = `${AUCTIONEER_URL}/user_intent`;
|
|
17
17
|
const response = await fetch(url, {
|
|
@@ -30,4 +30,4 @@ export class AuctioneerAPI {
|
|
|
30
30
|
|
|
31
31
|
return data.data!;
|
|
32
32
|
}
|
|
33
|
-
}
|
|
33
|
+
}
|
|
@@ -112,6 +112,10 @@ export class CrossChainOrder {
|
|
|
112
112
|
user: input.user,
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
+
if (isEvmChain(order.sourceChainId)) {
|
|
116
|
+
return order;
|
|
117
|
+
}
|
|
118
|
+
|
|
115
119
|
const randomPreparedData = order.getRandomPreparedData();
|
|
116
120
|
const intentRequest = order.toIntentRequest(randomPreparedData);
|
|
117
121
|
await BaseSDK.validateCrossChainOrder(intentRequest);
|
|
@@ -244,7 +248,7 @@ export class CrossChainOrder {
|
|
|
244
248
|
* @returns Object containing source chain-specific data
|
|
245
249
|
*/
|
|
246
250
|
public toSourceChainData() {
|
|
247
|
-
|
|
251
|
+
const data: SourceChainData = {
|
|
248
252
|
user: this.user,
|
|
249
253
|
srcChainId: this.sourceChainId,
|
|
250
254
|
tokenIn: this.sourceTokenAddress,
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// src/core/orders/dca-single-chain.ts
|
|
2
|
+
import { ChainID, chainIdToChainTypeMap, isEvmChain, type SupportedChain } from '../../chains.js';
|
|
3
|
+
import { ValidationError } from '../../errors/index.js';
|
|
4
|
+
import type { ApiResponse } from '../../types/api.js';
|
|
5
|
+
import type { DcaSingleChainPreparedData, DcaSingleChainUserIntentRequest } from '../../types/intent.js';
|
|
6
|
+
import { DcaSingleChainOrderValidator } from '../../utils/order-validator.js';
|
|
7
|
+
import { BaseSDK } from '../sdk.js';
|
|
8
|
+
import { getEVMDcaSingleChainOrderTypedData } from '../evm/order-signature.js';
|
|
9
|
+
import { type ExtraTransfer } from './common.js';
|
|
10
|
+
import { getSolanaDcaSingleChainOrderInstructions } from '../solana/dca/create-order.js';
|
|
11
|
+
|
|
12
|
+
export type CreateDcaSingleChainOrderParams = {
|
|
13
|
+
chainId: SupportedChain;
|
|
14
|
+
tokenIn: string;
|
|
15
|
+
tokenOut: string;
|
|
16
|
+
destinationAddress: string;
|
|
17
|
+
startTime: number;
|
|
18
|
+
amountInPerInterval: bigint;
|
|
19
|
+
totalIntervals: number;
|
|
20
|
+
intervalDuration: number;
|
|
21
|
+
amountOutMin?: bigint;
|
|
22
|
+
extraTransfers?: ExtraTransfer[];
|
|
23
|
+
deadline: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export class DcaSingleChainOrder {
|
|
27
|
+
public user: string;
|
|
28
|
+
public chainId: SupportedChain;
|
|
29
|
+
public tokenIn: string;
|
|
30
|
+
public tokenOut: string;
|
|
31
|
+
public destinationAddress: string;
|
|
32
|
+
public startTime: number;
|
|
33
|
+
public amountInPerInterval: bigint | number;
|
|
34
|
+
public totalIntervals: number;
|
|
35
|
+
public intervalDuration: number;
|
|
36
|
+
public amountOutMin: bigint | number;
|
|
37
|
+
public extraTransfers?: ExtraTransfer[];
|
|
38
|
+
public deadline: number;
|
|
39
|
+
|
|
40
|
+
private constructor(params: CreateDcaSingleChainOrderParams & { user: string }) {
|
|
41
|
+
this.user = params.user;
|
|
42
|
+
this.chainId = params.chainId;
|
|
43
|
+
this.tokenIn = params.tokenIn;
|
|
44
|
+
this.tokenOut = params.tokenOut;
|
|
45
|
+
this.destinationAddress = params.destinationAddress;
|
|
46
|
+
this.startTime = params.startTime;
|
|
47
|
+
this.amountInPerInterval = params.amountInPerInterval;
|
|
48
|
+
this.totalIntervals = params.totalIntervals;
|
|
49
|
+
this.intervalDuration = params.intervalDuration;
|
|
50
|
+
this.amountOutMin = params.amountOutMin ?? 1n;
|
|
51
|
+
this.extraTransfers = params.extraTransfers;
|
|
52
|
+
this.deadline = params.deadline;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public static async create(input: CreateDcaSingleChainOrderParams & { user: string }): Promise<DcaSingleChainOrder> {
|
|
56
|
+
new DcaSingleChainOrderValidator().validateOrder(input);
|
|
57
|
+
|
|
58
|
+
const order = new DcaSingleChainOrder({
|
|
59
|
+
...input,
|
|
60
|
+
user: input.user,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (isEvmChain(order.chainId)) {
|
|
64
|
+
return order;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const preparedRandomData = order.getRandomPreparedData();
|
|
68
|
+
const intentRequest = order.toIntentRequest(preparedRandomData);
|
|
69
|
+
await BaseSDK.validateDcaSingleChainOrder(intentRequest);
|
|
70
|
+
|
|
71
|
+
return order;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/// This is needed because API requires the prepared data to be sent
|
|
75
|
+
/// In the cases of Solana and Sui, if we want the real data, we must send the order on-chain before validating.
|
|
76
|
+
/// And that is something we cannot do before validating the order on the API side.
|
|
77
|
+
private getRandomPreparedData(): DcaSingleChainPreparedData {
|
|
78
|
+
const chainId = this.chainId;
|
|
79
|
+
const chainType = chainIdToChainTypeMap[chainId];
|
|
80
|
+
|
|
81
|
+
const randomNumber = String(Math.floor(Math.random() * 10000000));
|
|
82
|
+
|
|
83
|
+
switch (chainType) {
|
|
84
|
+
case 'EVM': {
|
|
85
|
+
return {
|
|
86
|
+
nonce: randomNumber,
|
|
87
|
+
signature: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
case 'Solana': {
|
|
91
|
+
return {
|
|
92
|
+
secretNumber: randomNumber,
|
|
93
|
+
orderPubkey: 'DFNAjFAvS4GF98Tp1kiyLvEHM3wjGXibCfF86nnmhuVc',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
case 'Sui': {
|
|
97
|
+
throw new ValidationError('DCA orders are not supported on Sui');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
default: {
|
|
101
|
+
throw new Error('Chain type not supported');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public getTotalAmountIn(): bigint {
|
|
107
|
+
return BigInt(this.amountInPerInterval) * BigInt(this.totalIntervals);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public toIntentRequest(preparedData: DcaSingleChainPreparedData): DcaSingleChainUserIntentRequest {
|
|
111
|
+
const sourceChainType = chainIdToChainTypeMap[this.chainId];
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
genericData: this,
|
|
115
|
+
chainSpecificData: {
|
|
116
|
+
[sourceChainType]: preparedData,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public sendToAuctioneer(preparedData: DcaSingleChainPreparedData): Promise<ApiResponse> {
|
|
122
|
+
return BaseSDK.sendDcaSingleChainOrder({
|
|
123
|
+
order: this,
|
|
124
|
+
preparedData,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public async toEVMTypedData() {
|
|
129
|
+
if (!isEvmChain(this.chainId)) {
|
|
130
|
+
throw new ValidationError('Chain id is not an Ethereum compatible chain');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return getEVMDcaSingleChainOrderTypedData(this);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
public async toSolanaInstructionsByteArray() {
|
|
137
|
+
if (this.chainId !== ChainID.Solana) {
|
|
138
|
+
throw new ValidationError('Chain id is not Solana');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return getSolanaDcaSingleChainOrderInstructions(this);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -63,8 +63,14 @@ export class SingleChainOrder {
|
|
|
63
63
|
user: input.user,
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
if (isEvmChain(order.chainId)) {
|
|
67
|
+
return order;
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
const preparedRandomData = order.getRandomPreparedData();
|
|
67
71
|
const intentRequest = order.toIntentRequest(preparedRandomData);
|
|
72
|
+
|
|
73
|
+
// Just validate for non EVM
|
|
68
74
|
await BaseSDK.validateSingleChainOrder(intentRequest);
|
|
69
75
|
|
|
70
76
|
return order;
|
|
@@ -106,7 +112,7 @@ export class SingleChainOrder {
|
|
|
106
112
|
});
|
|
107
113
|
|
|
108
114
|
switch (scenario) {
|
|
109
|
-
case 'QUOTE_REQUIRED':
|
|
115
|
+
case 'QUOTE_REQUIRED': {
|
|
110
116
|
const quote = await QuoteProvider.getSingleChainQuote({
|
|
111
117
|
tokenIn: input.tokenIn,
|
|
112
118
|
amount: input.amountIn,
|
|
@@ -114,6 +120,7 @@ export class SingleChainOrder {
|
|
|
114
120
|
tokenOut: input.tokenOut,
|
|
115
121
|
});
|
|
116
122
|
return (quote.amountOut * 93n) / 100n; // Add 7% reduced fixed amount to cover fees
|
|
123
|
+
}
|
|
117
124
|
|
|
118
125
|
case 'USE_PROVIDED_AMOUNT':
|
|
119
126
|
return amountOutMin!;
|
package/src/core/sdk.ts
CHANGED
|
@@ -4,119 +4,69 @@ import type { ApiResponse } from '../types/api.js';
|
|
|
4
4
|
import type {
|
|
5
5
|
CrossChainOrderPrepared,
|
|
6
6
|
CrossChainUserIntentRequest,
|
|
7
|
+
DcaSingleChainOrderPrepared,
|
|
8
|
+
DcaSingleChainUserIntentRequest,
|
|
7
9
|
SingleChainOrderPrepared,
|
|
8
10
|
SingleChainUserIntentRequest,
|
|
9
11
|
} from '../types/intent.js';
|
|
10
12
|
import { Parsers } from '../utils/parsers.js';
|
|
11
13
|
import { CrossChainOrder, type CreateCrossChainOrderParams } from './orders/cross-chain.js';
|
|
14
|
+
import { DcaSingleChainOrder, type CreateDcaSingleChainOrderParams } from './orders/dca-single-chain.js';
|
|
12
15
|
import { SingleChainOrder, type CreateSingleChainOrderParams } from './orders/single-chain.js';
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* Base SDK providing common functionality for all blockchain implementations
|
|
16
|
-
*
|
|
17
|
-
* This abstract class serves as the foundation for chain-specific SDK implementations
|
|
18
|
-
* (EVM, Solana, Sui), providing shared functionality for creating and sending orders
|
|
19
|
-
* across different blockchains.
|
|
20
19
|
*/
|
|
21
20
|
export abstract class BaseSDK {
|
|
22
21
|
public abstract getUserAddress(): Promise<string>;
|
|
23
|
-
protected abstract prepareCrossChainOrder(order: CrossChainOrder): Promise<CrossChainOrderPrepared>;
|
|
24
|
-
protected abstract prepareSingleChainOrder(order: SingleChainOrder): Promise<SingleChainOrderPrepared>;
|
|
25
|
-
|
|
26
|
-
public async createSingleChainOrder(params: CreateSingleChainOrderParams): Promise<SingleChainOrderPrepared> {
|
|
27
|
-
const userAddress = await this.getUserAddress();
|
|
28
|
-
|
|
29
|
-
const order = await SingleChainOrder.create({
|
|
30
|
-
...params,
|
|
31
|
-
user: userAddress,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
return this.prepareSingleChainOrder(order);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public async createCrossChainOrder(params: CreateCrossChainOrderParams): Promise<CrossChainOrderPrepared> {
|
|
38
|
-
const userAddress = await this.getUserAddress();
|
|
39
|
-
|
|
40
|
-
const order = await CrossChainOrder.create({
|
|
41
|
-
...params,
|
|
42
|
-
user: userAddress,
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
return this.prepareCrossChainOrder(order);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public async createAndSendSingleChainOrder(params: CreateSingleChainOrderParams): Promise<ApiResponse> {
|
|
49
|
-
const preparedOrder = await this.createSingleChainOrder(params);
|
|
50
|
-
return BaseSDK.sendSingleChainOrder(preparedOrder);
|
|
51
|
-
}
|
|
52
22
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
23
|
+
protected abstract prepareCrossChainOrder(order: CrossChainOrder): Promise<CrossChainOrderPrepared>;
|
|
24
|
+
protected prepareSingleChainOrder?(order: SingleChainOrder): Promise<SingleChainOrderPrepared>;
|
|
25
|
+
protected prepareDcaSingleChainOrder?(order: DcaSingleChainOrder): Promise<DcaSingleChainOrderPrepared>;
|
|
56
26
|
|
|
57
|
-
|
|
27
|
+
// Generic HTTP request handler
|
|
28
|
+
private static async makeRequest(url: string, body: string): Promise<ApiResponse> {
|
|
58
29
|
const response = await fetch(url, {
|
|
59
30
|
method: 'POST',
|
|
60
|
-
headers: {
|
|
61
|
-
'Content-Type': 'application/json',
|
|
62
|
-
},
|
|
31
|
+
headers: { 'Content-Type': 'application/json' },
|
|
63
32
|
body,
|
|
64
33
|
});
|
|
65
34
|
|
|
66
35
|
if (!response.ok) {
|
|
67
36
|
const errorJson: ApiResponse = await response.json();
|
|
68
|
-
|
|
37
|
+
const mainError = errorJson.error;
|
|
69
38
|
const extraErrorData = errorJson.extra_error_data;
|
|
70
|
-
|
|
39
|
+
|
|
40
|
+
const errorMessage = mainError
|
|
41
|
+
? `${mainError}. Extra error data: ${extraErrorData}`
|
|
42
|
+
: `Server error ${extraErrorData}`;
|
|
43
|
+
|
|
44
|
+
throw new NetworkError(errorMessage);
|
|
71
45
|
}
|
|
72
46
|
|
|
73
47
|
return response.json();
|
|
74
48
|
}
|
|
75
49
|
|
|
76
|
-
|
|
50
|
+
private static async validateOrder<T>(intentRequest: T, endpoint: string): Promise<void> {
|
|
77
51
|
const body = JSON.stringify(intentRequest, Parsers.bigIntReplacer);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const response = await fetch(url, {
|
|
81
|
-
method: 'POST',
|
|
82
|
-
headers: {
|
|
83
|
-
'Content-Type': 'application/json',
|
|
84
|
-
},
|
|
85
|
-
body,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
if (!response.ok) {
|
|
89
|
-
const errorJson: ApiResponse = await response.json();
|
|
90
|
-
|
|
91
|
-
const mainError = errorJson.error;
|
|
92
|
-
const extraErrorData = errorJson.extra_error_data;
|
|
93
|
-
throw new NetworkError(`Validation error: ${mainError}. Extra error data: ${extraErrorData}`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return;
|
|
52
|
+
const url = `${AUCTIONEER_URL}${endpoint}`;
|
|
53
|
+
await BaseSDK.makeRequest(url, body);
|
|
97
54
|
}
|
|
98
55
|
|
|
99
|
-
|
|
56
|
+
private static async sendOrder<T extends { toIntentRequest(preparedData: any): any }>(
|
|
57
|
+
preparedOrder: { order: T; preparedData: any },
|
|
58
|
+
endpoint: string,
|
|
59
|
+
): Promise<ApiResponse> {
|
|
60
|
+
const intentRequest = preparedOrder.order.toIntentRequest(preparedOrder.preparedData);
|
|
100
61
|
const body = JSON.stringify(intentRequest, Parsers.bigIntReplacer);
|
|
62
|
+
const url = `${AUCTIONEER_URL}${endpoint}`;
|
|
63
|
+
return BaseSDK.makeRequest(url, body);
|
|
64
|
+
}
|
|
101
65
|
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
'Content-Type': 'application/json',
|
|
107
|
-
},
|
|
108
|
-
body,
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
if (!response.ok) {
|
|
112
|
-
const errorJson: ApiResponse = await response.json();
|
|
113
|
-
|
|
114
|
-
const mainError = errorJson.error;
|
|
115
|
-
const extraErrorData = errorJson.extra_error_data;
|
|
116
|
-
throw new NetworkError(`Validation error: ${mainError}. Extra error data: ${extraErrorData}`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return;
|
|
66
|
+
public async createCrossChainOrder(params: CreateCrossChainOrderParams): Promise<CrossChainOrderPrepared> {
|
|
67
|
+
const userAddress = await this.getUserAddress();
|
|
68
|
+
const order = await CrossChainOrder.create({ ...params, user: userAddress });
|
|
69
|
+
return this.prepareCrossChainOrder!(order);
|
|
120
70
|
}
|
|
121
71
|
|
|
122
72
|
public async createAndSendCrossChainOrder(params: CreateCrossChainOrderParams): Promise<ApiResponse> {
|
|
@@ -125,28 +75,50 @@ export abstract class BaseSDK {
|
|
|
125
75
|
}
|
|
126
76
|
|
|
127
77
|
public static async sendCrossChainOrder(preparedOrder: CrossChainOrderPrepared): Promise<ApiResponse> {
|
|
128
|
-
|
|
129
|
-
|
|
78
|
+
return BaseSDK.sendOrder(preparedOrder, '/user_intent/cross_chain/limit_order');
|
|
79
|
+
}
|
|
130
80
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
headers: {
|
|
135
|
-
'Content-Type': 'application/json',
|
|
136
|
-
},
|
|
137
|
-
body,
|
|
138
|
-
});
|
|
81
|
+
public static async validateCrossChainOrder(intentRequest: CrossChainUserIntentRequest): Promise<void> {
|
|
82
|
+
return BaseSDK.validateOrder(intentRequest, '/validate_intent/cross_chain/limit_order');
|
|
83
|
+
}
|
|
139
84
|
|
|
140
|
-
|
|
141
|
-
|
|
85
|
+
public async createSingleChainOrder(params: CreateSingleChainOrderParams): Promise<SingleChainOrderPrepared> {
|
|
86
|
+
const userAddress = await this.getUserAddress();
|
|
87
|
+
const order = await SingleChainOrder.create({ ...params, user: userAddress });
|
|
88
|
+
return this.prepareSingleChainOrder!(order);
|
|
89
|
+
}
|
|
142
90
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
);
|
|
148
|
-
}
|
|
91
|
+
public async createAndSendSingleChainOrder(params: CreateSingleChainOrderParams): Promise<ApiResponse> {
|
|
92
|
+
const preparedOrder = await this.createSingleChainOrder(params);
|
|
93
|
+
return BaseSDK.sendSingleChainOrder(preparedOrder);
|
|
94
|
+
}
|
|
149
95
|
|
|
150
|
-
|
|
96
|
+
public static async sendSingleChainOrder(preparedOrder: SingleChainOrderPrepared): Promise<ApiResponse> {
|
|
97
|
+
return BaseSDK.sendOrder(preparedOrder, '/user_intent/single_chain/limit_order');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public static async validateSingleChainOrder(intentRequest: SingleChainUserIntentRequest): Promise<void> {
|
|
101
|
+
return BaseSDK.validateOrder(intentRequest, '/validate_intent/single_chain/limit_order');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public async createDcaSingleChainOrder(
|
|
105
|
+
params: CreateDcaSingleChainOrderParams,
|
|
106
|
+
): Promise<DcaSingleChainOrderPrepared> {
|
|
107
|
+
const userAddress = await this.getUserAddress();
|
|
108
|
+
const order = await DcaSingleChainOrder.create({ ...params, user: userAddress });
|
|
109
|
+
return this.prepareDcaSingleChainOrder!(order);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public async createAndSendDcaSingleChainOrder(params: CreateDcaSingleChainOrderParams): Promise<ApiResponse> {
|
|
113
|
+
const preparedOrder = await this.createDcaSingleChainOrder(params);
|
|
114
|
+
return BaseSDK.sendDcaSingleChainOrder(preparedOrder);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public static async sendDcaSingleChainOrder(preparedOrder: DcaSingleChainOrderPrepared): Promise<ApiResponse> {
|
|
118
|
+
return BaseSDK.sendOrder(preparedOrder, '/user_intent/single_chain/dca_order');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public static async validateDcaSingleChainOrder(intentRequest: DcaSingleChainUserIntentRequest): Promise<void> {
|
|
122
|
+
return BaseSDK.validateOrder(intentRequest, '/validate_intent/single_chain/dca_order');
|
|
151
123
|
}
|
|
152
124
|
}
|
|
@@ -164,7 +164,7 @@ export async function cancelCrossChainOrderInstructions(
|
|
|
164
164
|
const addressEncoder = getAddressEncoder();
|
|
165
165
|
|
|
166
166
|
const isRecoveringTokenIn = chainOrder.data.lockedStablecoins === 0n;
|
|
167
|
-
const recoverTokenMint = isRecoveringTokenIn ? chainOrder.data.tokenInMint : address(SOLANA_MINT_TOKEN.mint);
|
|
167
|
+
const recoverTokenMint = isRecoveringTokenIn ? chainOrder.data.tokenInMint : address(SOLANA_MINT_TOKEN.mint);
|
|
168
168
|
|
|
169
169
|
const recoverTokenMintProgram = await fetchMint(rpc, recoverTokenMint);
|
|
170
170
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {
|
|
2
|
+
address,
|
|
3
|
+
createNoopSigner,
|
|
4
|
+
createSolanaRpc,
|
|
5
|
+
fetchEncodedAccount,
|
|
6
|
+
getAddressEncoder,
|
|
7
|
+
getProgramDerivedAddress,
|
|
8
|
+
type Address,
|
|
9
|
+
type IInstruction,
|
|
10
|
+
} from '@solana/kit';
|
|
11
|
+
import { getDefaultSolanaRPC } from '../client.js';
|
|
12
|
+
import { fetchMaybeDcaOrder, getCancelDcaOrderInstruction } from '../generated/single-chain/index.js';
|
|
13
|
+
import {
|
|
14
|
+
ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
15
|
+
fetchMint,
|
|
16
|
+
getCreateAssociatedTokenInstructionAsync,
|
|
17
|
+
} from '@solana-program/token';
|
|
18
|
+
import { SINGLE_CHAIN_GUARD_ADDRESSES } from '../../../constants.js';
|
|
19
|
+
import { ChainID } from '../../../chains.js';
|
|
20
|
+
|
|
21
|
+
export async function cancelDcaSingleChainOrderInstructions(
|
|
22
|
+
orderAddress: string,
|
|
23
|
+
options?: { rpcUrl?: string },
|
|
24
|
+
): Promise<IInstruction[]> {
|
|
25
|
+
const rpc = options?.rpcUrl ? createSolanaRpc(options.rpcUrl) : getDefaultSolanaRPC();
|
|
26
|
+
|
|
27
|
+
const orderId = address(orderAddress);
|
|
28
|
+
const chainOrder = await fetchMaybeDcaOrder(rpc, orderId);
|
|
29
|
+
|
|
30
|
+
if (!chainOrder.exists) {
|
|
31
|
+
throw new Error(`Order with address ${orderAddress} not found`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const instructions: IInstruction[] = [];
|
|
35
|
+
const orderUserAddress = chainOrder.data.user;
|
|
36
|
+
|
|
37
|
+
const tokenInMint = chainOrder.data.tokenInMint;
|
|
38
|
+
|
|
39
|
+
const tokenMintProgram = await fetchMint(rpc, tokenInMint);
|
|
40
|
+
|
|
41
|
+
const addressEncoder = getAddressEncoder();
|
|
42
|
+
|
|
43
|
+
const [tokenInProgramAccount] = await getProgramDerivedAddress({
|
|
44
|
+
programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
45
|
+
seeds: [
|
|
46
|
+
addressEncoder.encode(orderUserAddress),
|
|
47
|
+
addressEncoder.encode(tokenMintProgram.programAddress),
|
|
48
|
+
addressEncoder.encode(tokenInMint),
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const guardAddress = SINGLE_CHAIN_GUARD_ADDRESSES[ChainID.Solana] as Address;
|
|
53
|
+
const [guardProgramAccount] = await getProgramDerivedAddress({
|
|
54
|
+
programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
55
|
+
seeds: [
|
|
56
|
+
// Owner
|
|
57
|
+
addressEncoder.encode(guardAddress),
|
|
58
|
+
// Token program
|
|
59
|
+
addressEncoder.encode(tokenMintProgram.programAddress),
|
|
60
|
+
// mint address
|
|
61
|
+
addressEncoder.encode(tokenInMint),
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const userTokenInAccount = await fetchEncodedAccount(rpc, tokenInProgramAccount);
|
|
66
|
+
|
|
67
|
+
if (!userTokenInAccount.exists) {
|
|
68
|
+
const createTokenIx = await getCreateAssociatedTokenInstructionAsync({
|
|
69
|
+
mint: tokenInMint,
|
|
70
|
+
owner: orderUserAddress,
|
|
71
|
+
payer: createNoopSigner(orderUserAddress),
|
|
72
|
+
tokenProgram: tokenMintProgram.programAddress,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
instructions.push(createTokenIx);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const cancelLimitOrderIx = getCancelDcaOrderInstruction({
|
|
79
|
+
user: createNoopSigner(orderUserAddress),
|
|
80
|
+
order: orderId,
|
|
81
|
+
guard: guardAddress,
|
|
82
|
+
tokenInMint: chainOrder.data.tokenInMint,
|
|
83
|
+
userTokenInAccount: userTokenInAccount.address,
|
|
84
|
+
guardTokenInAccount: guardProgramAccount,
|
|
85
|
+
tokenInProgram: tokenMintProgram.programAddress,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
instructions.push(cancelLimitOrderIx);
|
|
89
|
+
|
|
90
|
+
return instructions;
|
|
91
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
address,
|
|
3
|
+
addSignersToTransactionMessage,
|
|
4
|
+
appendTransactionMessageInstructions,
|
|
5
|
+
createNoopSigner,
|
|
6
|
+
createSolanaRpc,
|
|
7
|
+
createTransactionMessage,
|
|
8
|
+
fetchEncodedAccount,
|
|
9
|
+
generateKeyPairSigner,
|
|
10
|
+
getAddressEncoder,
|
|
11
|
+
getProgramDerivedAddress,
|
|
12
|
+
getTransactionCodec,
|
|
13
|
+
partiallySignTransactionMessageWithSigners,
|
|
14
|
+
pipe,
|
|
15
|
+
setTransactionMessageFeePayerSigner,
|
|
16
|
+
setTransactionMessageLifetimeUsingBlockhash,
|
|
17
|
+
type Address,
|
|
18
|
+
type IInstruction,
|
|
19
|
+
} from '@solana/kit';
|
|
20
|
+
import type { DcaSingleChainOrder } from '../../orders/dca-single-chain.js';
|
|
21
|
+
import type { SolanaOrderInstructionResult } from '../order-instructions.js';
|
|
22
|
+
import { getDefaultSolanaRPC } from '../client.js';
|
|
23
|
+
import { genSecretHashAndNumber } from '../utils.js';
|
|
24
|
+
import {
|
|
25
|
+
NATIVE_SOLANA_TOKEN_ADDRESS,
|
|
26
|
+
SINGLE_CHAIN_GUARD_ADDRESSES,
|
|
27
|
+
WRAPPED_SOL_MINT_ADDRESS,
|
|
28
|
+
} from '../../../constants.js';
|
|
29
|
+
import {
|
|
30
|
+
ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
31
|
+
fetchMint,
|
|
32
|
+
getCreateAssociatedTokenInstructionAsync,
|
|
33
|
+
getSyncNativeInstruction,
|
|
34
|
+
} from '@solana-program/token';
|
|
35
|
+
import { ChainID } from '../../../chains.js';
|
|
36
|
+
import { getTransferSolInstruction } from '@solana-program/system';
|
|
37
|
+
import { getCreateDcaOrderInstructionAsync } from '../generated/single-chain/index.js';
|
|
38
|
+
|
|
39
|
+
export async function getSolanaDcaSingleChainOrderInstructions(
|
|
40
|
+
order: DcaSingleChainOrder,
|
|
41
|
+
options?: { rpcUrl?: string },
|
|
42
|
+
): Promise<SolanaOrderInstructionResult & { secretNumber: string }> {
|
|
43
|
+
const rpc = options?.rpcUrl ? createSolanaRpc(options.rpcUrl) : getDefaultSolanaRPC();
|
|
44
|
+
const orderSigner = await generateKeyPairSigner();
|
|
45
|
+
const signer = createNoopSigner(order.user as Address);
|
|
46
|
+
|
|
47
|
+
let tokenInMint = address(order.tokenIn);
|
|
48
|
+
|
|
49
|
+
const { secretHash, secretNumber } = genSecretHashAndNumber(order);
|
|
50
|
+
|
|
51
|
+
const orderUserAddress = address(order.user);
|
|
52
|
+
const spendingNative = tokenInMint === NATIVE_SOLANA_TOKEN_ADDRESS;
|
|
53
|
+
|
|
54
|
+
if (spendingNative) {
|
|
55
|
+
tokenInMint = WRAPPED_SOL_MINT_ADDRESS;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const tokenMintProgram = await fetchMint(rpc, tokenInMint);
|
|
59
|
+
|
|
60
|
+
const guardAddress = address(SINGLE_CHAIN_GUARD_ADDRESSES[ChainID.Solana]); // Assuming DCA uses same guard
|
|
61
|
+
const addressEncoder = getAddressEncoder();
|
|
62
|
+
const instructions: Array<IInstruction> = [];
|
|
63
|
+
|
|
64
|
+
const [tokenInProgramAccount] = await getProgramDerivedAddress({
|
|
65
|
+
programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
66
|
+
seeds: [
|
|
67
|
+
addressEncoder.encode(orderUserAddress),
|
|
68
|
+
addressEncoder.encode(tokenMintProgram.programAddress),
|
|
69
|
+
addressEncoder.encode(tokenInMint),
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const userTokenInAccount = await fetchEncodedAccount(rpc, tokenInProgramAccount);
|
|
74
|
+
|
|
75
|
+
if (!userTokenInAccount.exists) {
|
|
76
|
+
const createAccountIx = await getCreateAssociatedTokenInstructionAsync({
|
|
77
|
+
payer: signer,
|
|
78
|
+
ata: tokenInProgramAccount,
|
|
79
|
+
owner: orderUserAddress,
|
|
80
|
+
mint: tokenMintProgram.address,
|
|
81
|
+
tokenProgram: tokenMintProgram.programAddress,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
instructions.push(createAccountIx);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const totalAmountIn = BigInt(order.amountInPerInterval) * BigInt(order.totalIntervals);
|
|
88
|
+
|
|
89
|
+
if (spendingNative) {
|
|
90
|
+
const transferIx = getTransferSolInstruction({
|
|
91
|
+
amount: totalAmountIn,
|
|
92
|
+
destination: userTokenInAccount.address,
|
|
93
|
+
source: signer,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
instructions.push(transferIx);
|
|
97
|
+
|
|
98
|
+
const syncNativeIx = getSyncNativeInstruction({
|
|
99
|
+
account: userTokenInAccount.address,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
instructions.push(syncNativeIx);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const createDcaOrderIx = await getCreateDcaOrderInstructionAsync({
|
|
106
|
+
user: signer,
|
|
107
|
+
order: orderSigner,
|
|
108
|
+
guard: guardAddress,
|
|
109
|
+
tokenInMint: tokenInMint,
|
|
110
|
+
userTokenInAccount: userTokenInAccount.address,
|
|
111
|
+
tokenInProgram: tokenMintProgram.programAddress,
|
|
112
|
+
amountInPerInterval: order.amountInPerInterval,
|
|
113
|
+
totalIntervals: order.totalIntervals,
|
|
114
|
+
intervalDuration: order.intervalDuration,
|
|
115
|
+
deadline: order.deadline,
|
|
116
|
+
amountOutMin: order.amountOutMin,
|
|
117
|
+
secretHash: Uint8Array.from(secretHash),
|
|
118
|
+
extraTransfersAmounts: [], // TODO: Implement extra transfers
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
instructions.push(createDcaOrderIx);
|
|
122
|
+
|
|
123
|
+
const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'confirmed' }).send();
|
|
124
|
+
|
|
125
|
+
const txMessage = pipe(
|
|
126
|
+
createTransactionMessage({ version: 0 }),
|
|
127
|
+
(tx) => setTransactionMessageFeePayerSigner(signer, tx),
|
|
128
|
+
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
|
|
129
|
+
(tx) => appendTransactionMessageInstructions(instructions, tx),
|
|
130
|
+
(tx) => addSignersToTransactionMessage([orderSigner], tx),
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const partiallySignedTransaction = await partiallySignTransactionMessageWithSigners(txMessage);
|
|
134
|
+
|
|
135
|
+
const txBytes = getTransactionCodec().encode(partiallySignedTransaction);
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
orderAddress: orderSigner.address,
|
|
139
|
+
txBytes,
|
|
140
|
+
secretNumber,
|
|
141
|
+
};
|
|
142
|
+
}
|