@shogun-sdk/intents-sdk 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +5 -0
- 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 +3 -0
- 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 +4 -0
- 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/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/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/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 +16 -3
- 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 +4 -0
- package/src/core/orders/dca-single-chain.ts +143 -0
- package/src/core/orders/single-chain.ts +6 -0
- 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/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/liquidswap.ts +2 -2
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { address, createSolanaRpc, type Base58EncodedBytes } from '@solana/kit';
|
|
2
|
+
import { getDefaultSolanaRPC } from './client.js';
|
|
3
|
+
import { logger } from '../../utils/logger.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Inspect Solana guards to find orders that are currently locked on-chain.
|
|
7
|
+
* @param userAddress - The user's Solana address
|
|
8
|
+
* @param config - The Solana RPC configuration
|
|
9
|
+
* @returns An object containing the Solana guard programs for cross-chain and single-chain orders
|
|
10
|
+
*/
|
|
11
|
+
export async function getSolanaOrdersWithLockedFunds(userAddress: string, config?: { rpcUrl?: string }) {
|
|
12
|
+
const rpc = config?.rpcUrl ? createSolanaRpc(config.rpcUrl) : getDefaultSolanaRPC();
|
|
13
|
+
|
|
14
|
+
// const singleChainGuardAddress = SINGLE_CHAIN_GUARD_ADDRESSES[ChainID.Solana];
|
|
15
|
+
|
|
16
|
+
const programAccountAddress = address('43cctGU9QJ4WEPzLoNEvo3TPiv6nMUG9puN2pXQSnB6V');
|
|
17
|
+
const programAccountsConfig = {
|
|
18
|
+
encoding: 'base64',
|
|
19
|
+
filters: [
|
|
20
|
+
{
|
|
21
|
+
memcmp: {
|
|
22
|
+
offset: 8n,
|
|
23
|
+
encoding: 'base58',
|
|
24
|
+
bytes: userAddress as Base58EncodedBytes,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
} as Readonly<unknown>;
|
|
29
|
+
|
|
30
|
+
logger.info(`Fetching cross-chain guard programs for user: ${userAddress}`);
|
|
31
|
+
const crossChainGuardPrograms = await rpc.getProgramAccounts(programAccountAddress, programAccountsConfig).send();
|
|
32
|
+
logger.info(`Found ${crossChainGuardPrograms.length} cross-chain guard programs`);
|
|
33
|
+
// const singleChainGuardPrograms = await rpc.getProgramAccounts(address(singleChainGuardAddress), programAccountsConfig).send();
|
|
34
|
+
|
|
35
|
+
// const crossChainCodec = getOrderCodec();
|
|
36
|
+
// const singleChainCodec = getLimitOrderCodec();
|
|
37
|
+
// const base64Encoder = getBase64Encoder();
|
|
38
|
+
|
|
39
|
+
const crossChainGuardProgramsWithOrders = crossChainGuardPrograms.map(({ pubkey, account }) => {
|
|
40
|
+
logger.info(`Account data: ${account} and pubkey: ${pubkey}`);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
pubkey,
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
crossChainGuardPrograms: crossChainGuardProgramsWithOrders,
|
|
49
|
+
};
|
|
50
|
+
}
|
package/src/core/solana/sdk.ts
CHANGED
|
@@ -22,12 +22,19 @@ import { BaseSDK } from '../sdk.js';
|
|
|
22
22
|
import { createSolanaClient, type SolanaClient } from './client.js';
|
|
23
23
|
import { cancelCrossChainOrderInstructions, cancelSingleChainOrderInstructions } from './cancel-order.js';
|
|
24
24
|
import type { CrossChainOrder } from '../orders/cross-chain.js';
|
|
25
|
-
import type {
|
|
25
|
+
import type {
|
|
26
|
+
CrossChainOrderPrepared,
|
|
27
|
+
DcaSingleChainOrderPrepared,
|
|
28
|
+
SingleChainOrderPrepared,
|
|
29
|
+
} from '../../types/intent.js';
|
|
26
30
|
import { getSolanaCrossChainOrderInstructions, getSolanaSingleChainOrderInstructions } from './order-instructions.js';
|
|
27
31
|
import type { SingleChainOrder } from '../orders/single-chain.js';
|
|
28
32
|
import { fetchJWTToken, fetchSiweMessage } from '../../auth/siwe.js';
|
|
29
33
|
import { ChainID } from '../../chains.js';
|
|
30
34
|
import { bytesToHex } from 'viem';
|
|
35
|
+
import type { DcaSingleChainOrder } from '../orders/dca-single-chain.js';
|
|
36
|
+
import { getSolanaDcaSingleChainOrderInstructions } from './dca/create-order.js';
|
|
37
|
+
import { cancelDcaSingleChainOrderInstructions } from './dca/cancel-order.js';
|
|
31
38
|
|
|
32
39
|
/**
|
|
33
40
|
* Solana-specific SDK implementation
|
|
@@ -224,7 +231,7 @@ export class SolanaSDK extends BaseSDK {
|
|
|
224
231
|
};
|
|
225
232
|
}
|
|
226
233
|
|
|
227
|
-
protected async prepareSingleChainOrder(order: SingleChainOrder): Promise<SingleChainOrderPrepared> {
|
|
234
|
+
protected override async prepareSingleChainOrder(order: SingleChainOrder): Promise<SingleChainOrderPrepared> {
|
|
228
235
|
const signerKeyPair = await this.getUserCryptoKeypair();
|
|
229
236
|
|
|
230
237
|
const { orderAddress, txBytes, secretNumber } = await getSolanaSingleChainOrderInstructions(order);
|
|
@@ -237,6 +244,62 @@ export class SolanaSDK extends BaseSDK {
|
|
|
237
244
|
|
|
238
245
|
const encodedTransaction = getBase64EncodedWireTransaction(signedTx);
|
|
239
246
|
|
|
247
|
+
await this.client.rpc
|
|
248
|
+
.sendTransaction(encodedTransaction, { preflightCommitment: this.config.commitment, encoding: 'base64' })
|
|
249
|
+
.send();
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
order,
|
|
253
|
+
preparedData: {
|
|
254
|
+
orderPubkey: orderAddress,
|
|
255
|
+
secretNumber,
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
public async cancelDcaSingleChainOrder(orderId: string): Promise<string> {
|
|
260
|
+
const instructions = await cancelDcaSingleChainOrderInstructions(orderId, { rpcUrl: this.config.rpcProviderUrl });
|
|
261
|
+
const signer = await this.getUserSigner();
|
|
262
|
+
const signerKeyPair = await this.getUserCryptoKeypair();
|
|
263
|
+
|
|
264
|
+
const noopSigner = createNoopSigner(signer.address);
|
|
265
|
+
|
|
266
|
+
const { value: latestBlockhash } = await this.client.rpc
|
|
267
|
+
.getLatestBlockhash({ commitment: this.config.commitment })
|
|
268
|
+
.send();
|
|
269
|
+
|
|
270
|
+
const transactionMessage = pipe(
|
|
271
|
+
createTransactionMessage({ version: 0 }),
|
|
272
|
+
(tx) => setTransactionMessageFeePayerSigner(noopSigner, tx),
|
|
273
|
+
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
|
|
274
|
+
(tx) => appendTransactionMessageInstructions(instructions, tx),
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
const myTx = compileTransaction(transactionMessage);
|
|
278
|
+
|
|
279
|
+
const signature = await signTransaction([signerKeyPair], myTx);
|
|
280
|
+
|
|
281
|
+
await this.client.sendAndConfirmTransaction(signature, {
|
|
282
|
+
commitment: this.config.commitment,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
return orderId;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
protected override async prepareDcaSingleChainOrder(
|
|
289
|
+
order: DcaSingleChainOrder,
|
|
290
|
+
): Promise<DcaSingleChainOrderPrepared> {
|
|
291
|
+
const signerKeyPair = await this.getUserCryptoKeypair();
|
|
292
|
+
|
|
293
|
+
const { orderAddress, txBytes, secretNumber } = await getSolanaDcaSingleChainOrderInstructions(order);
|
|
294
|
+
|
|
295
|
+
const transactionCodec = getTransactionCodec();
|
|
296
|
+
|
|
297
|
+
const tx = transactionCodec.decode(txBytes);
|
|
298
|
+
|
|
299
|
+
const signedTx = await partiallySignTransaction([signerKeyPair], tx);
|
|
300
|
+
|
|
301
|
+
const encodedTransaction = getBase64EncodedWireTransaction(signedTx);
|
|
302
|
+
|
|
240
303
|
await this.client.rpc
|
|
241
304
|
.sendTransaction(encodedTransaction, { preflightCommitment: this.config.commitment, encoding: 'base64' })
|
|
242
305
|
.send();
|
package/src/core/solana/utils.ts
CHANGED
|
@@ -2,8 +2,9 @@ import BN from 'bn.js';
|
|
|
2
2
|
import type { SingleChainOrder } from '../orders/single-chain.js';
|
|
3
3
|
import { PublicKey } from '@solana/web3.js';
|
|
4
4
|
import sha3 from 'js-sha3';
|
|
5
|
+
import type { DcaSingleChainOrder } from '../orders/dca-single-chain.js';
|
|
5
6
|
|
|
6
|
-
export function genSecretHashAndNumber(order: SingleChainOrder): {
|
|
7
|
+
export function genSecretHashAndNumber(order: SingleChainOrder | DcaSingleChainOrder): {
|
|
7
8
|
secretHash: number[];
|
|
8
9
|
secretNumber: string;
|
|
9
10
|
} {
|
package/src/core/sui/sdk.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { BaseSDK } from '../sdk.js';
|
|
|
5
5
|
import { createSuiClient } from './client.js';
|
|
6
6
|
import { getSuiOrderTransaction } from './order-transaction.js';
|
|
7
7
|
import { getSuiCancelCrossChainOrder } from './cancel.js';
|
|
8
|
-
import type { CrossChainOrderPrepared
|
|
8
|
+
import type { CrossChainOrderPrepared } from '../../types/intent.js';
|
|
9
9
|
import type { CrossChainOrder } from '../orders/cross-chain.js';
|
|
10
10
|
import { fetchJWTToken, fetchSiweMessage } from '../../auth/siwe.js';
|
|
11
11
|
import { ChainID } from '../../chains.js';
|
|
@@ -57,10 +57,6 @@ export class SuiSDK extends BaseSDK {
|
|
|
57
57
|
return Ed25519Keypair.fromSecretKey(this.config.privateKey);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
protected override prepareSingleChainOrder(): Promise<SingleChainOrderPrepared> {
|
|
61
|
-
throw new Error('Single-chain orders are not supported on Sui');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
60
|
public async authenticate(token?: string): Promise<string> {
|
|
65
61
|
const wallet = await this.getUserAddress();
|
|
66
62
|
|
|
@@ -103,7 +99,7 @@ export class SuiSDK extends BaseSDK {
|
|
|
103
99
|
* @returns Promise resolving to a prepared order with Sui-specific data
|
|
104
100
|
* @protected
|
|
105
101
|
*/
|
|
106
|
-
protected async prepareCrossChainOrder(order: CrossChainOrder): Promise<CrossChainOrderPrepared> {
|
|
102
|
+
protected override async prepareCrossChainOrder(order: CrossChainOrder): Promise<CrossChainOrderPrepared> {
|
|
107
103
|
const signer = this.getKeyPair();
|
|
108
104
|
|
|
109
105
|
const transaction = await getSuiOrderTransaction(order);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';
|
|
2
2
|
import { MAX_UINT_64 } from '../../constants.js';
|
|
3
3
|
import { BaseValidator } from '../../utils/base-validator.js';
|
|
4
|
+
import { ValidationError } from '../../errors/index.js';
|
|
4
5
|
|
|
5
6
|
const SUI_TOKEN_ADDRESS_REGEX = /^0x[a-fA-F0-9]{64}::\w+::\w+$/;
|
|
6
7
|
|
|
@@ -33,4 +34,8 @@ export class SuiValidator extends BaseValidator {
|
|
|
33
34
|
override validateSingleChainOrderFeasability(): Promise<void> {
|
|
34
35
|
return Promise.resolve();
|
|
35
36
|
}
|
|
37
|
+
|
|
38
|
+
override validateDcaSingleChainOrderFeasability(): Promise<void> {
|
|
39
|
+
throw new ValidationError('DCA orders are not supported on Sui');
|
|
40
|
+
}
|
|
36
41
|
}
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,15 @@ export { fetchUserOrders } from './core/orders/api/fetch.js';
|
|
|
14
14
|
export { AuctioneerAPI } from './core/orders/api/index.js';
|
|
15
15
|
export { type FetchJWTParams, type FetchSiweMessageParams, fetchJWTToken, fetchSiweMessage } from './auth/siwe.js';
|
|
16
16
|
export { ValidationError } from './errors/index.js';
|
|
17
|
-
export {
|
|
17
|
+
export {
|
|
18
|
+
type ApiCrossChainOrder,
|
|
19
|
+
type ApiResponse,
|
|
20
|
+
type ApiSingleChainOrder,
|
|
21
|
+
type ApiUserOrders,
|
|
22
|
+
type ChainOrderStatus,
|
|
23
|
+
isErrorApiResponse,
|
|
24
|
+
isSuccessApiResponse,
|
|
25
|
+
} from './types/api.js';
|
|
18
26
|
export { calculateAmounts, getCoinFromResponse, getTokensData } from './utils/defillama.js';
|
|
19
27
|
export type { DefiLlamaCoinData, DefiLlamaTokensResponse } from './utils/defillama.js';
|
|
20
28
|
export {
|
|
@@ -24,8 +32,11 @@ export {
|
|
|
24
32
|
type CancelCrossChainOrderParams,
|
|
25
33
|
getInvalidateNoncesRawData,
|
|
26
34
|
} from './core/evm/cancel-order.js';
|
|
35
|
+
export { cancelDcaSingleChainOrderInstructions } from './core/solana/dca/cancel-order.js';
|
|
27
36
|
export { getEVMCrossChainOrderTypedData, getEVMSingleChainOrderTypedData } from './core/evm/order-signature.js';
|
|
28
37
|
|
|
38
|
+
export { getSolanaOrdersWithLockedFunds } from './core/solana/inspect.js';
|
|
39
|
+
|
|
29
40
|
export {
|
|
30
41
|
getSolanaCrossChainOrderInstructions,
|
|
31
42
|
getSolanaSingleChainOrderInstructions,
|
package/src/types/api.ts
CHANGED
package/src/types/intent.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { SupportedChain } from '../chains.js';
|
|
|
2
2
|
import type { CrossChainOrder } from '../core/orders/cross-chain.js';
|
|
3
3
|
import type { ExtraTransfer } from '../core/orders/common.js';
|
|
4
4
|
import type { SingleChainOrder } from '../core/orders/single-chain.js';
|
|
5
|
+
import type { DcaSingleChainOrder } from '../core/orders/dca-single-chain.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Details required to execute the order on the destination chain
|
|
@@ -120,3 +121,29 @@ export type SingleChainOrderPrepared = {
|
|
|
120
121
|
order: SingleChainOrder;
|
|
121
122
|
preparedData: SingleChainPreparedData;
|
|
122
123
|
};
|
|
124
|
+
|
|
125
|
+
export type DcaSingleChainUserIntentRequest = {
|
|
126
|
+
genericData: DcaSingleChainOrder;
|
|
127
|
+
chainSpecificData: {
|
|
128
|
+
EVM?: DcaSingleChainEVMPreparedData;
|
|
129
|
+
Solana?: DcaSingleChainSolanaPreparedData;
|
|
130
|
+
Sui?: never; // DCA not supported on Sui
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export type DcaSingleChainEVMPreparedData = {
|
|
135
|
+
nonce: string;
|
|
136
|
+
signature: string | Hash;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export type DcaSingleChainSolanaPreparedData = {
|
|
140
|
+
secretNumber: string;
|
|
141
|
+
orderPubkey: string;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export type DcaSingleChainPreparedData = DcaSingleChainEVMPreparedData | DcaSingleChainSolanaPreparedData;
|
|
145
|
+
|
|
146
|
+
export type DcaSingleChainOrderPrepared = {
|
|
147
|
+
order: DcaSingleChainOrder;
|
|
148
|
+
preparedData: DcaSingleChainPreparedData;
|
|
149
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CreateCrossChainOrderParams } from '../core/orders/cross-chain.js';
|
|
2
|
+
import type { CreateDcaSingleChainOrderParams } from '../core/orders/dca-single-chain.js';
|
|
2
3
|
import type { CreateSingleChainOrderParams } from '../core/orders/single-chain.js';
|
|
3
4
|
import { ValidationError } from '../errors/index.js';
|
|
4
5
|
import type { IChainValidator } from './order-validator.js';
|
|
@@ -59,6 +60,45 @@ export abstract class BaseValidator implements IChainValidator {
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
abstract validateDcaSingleChainOrderFeasability(
|
|
64
|
+
order: CreateDcaSingleChainOrderParams & { user: string },
|
|
65
|
+
): Promise<void>;
|
|
66
|
+
|
|
67
|
+
async validateDcaSingleChainOrder(order: CreateDcaSingleChainOrderParams & { user: string }): Promise<void> {
|
|
68
|
+
this.validateTokenAddress(order.tokenIn);
|
|
69
|
+
this.validateTokenAddress(order.tokenOut);
|
|
70
|
+
this.validateAmount(order.amountInPerInterval);
|
|
71
|
+
this.validateAmount(order.amountOutMin ?? 1n);
|
|
72
|
+
this.validateAddress(order.destinationAddress);
|
|
73
|
+
|
|
74
|
+
// Validate DCA-specific parameters
|
|
75
|
+
if (order.totalIntervals <= 0) {
|
|
76
|
+
throw new ValidationError('Total intervals must be greater than 0');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (order.intervalDuration <= 0) {
|
|
80
|
+
throw new ValidationError('Interval duration must be greater than 0');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (order.startTime < 0) {
|
|
84
|
+
throw new ValidationError('Start time must be non-negative');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Validate total amount doesn't overflow
|
|
88
|
+
const totalAmount = order.amountInPerInterval * BigInt(order.totalIntervals);
|
|
89
|
+
this.validateAmount(totalAmount);
|
|
90
|
+
|
|
91
|
+
if (order.extraTransfers) {
|
|
92
|
+
for (const extraTransfer of order.extraTransfers) {
|
|
93
|
+
this.validateAddress(extraTransfer.receiver);
|
|
94
|
+
this.validateTokenAddress(extraTransfer.token);
|
|
95
|
+
this.validateAmount(extraTransfer.amount);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
await this.validateDcaSingleChainOrderFeasability(order);
|
|
100
|
+
}
|
|
101
|
+
|
|
62
102
|
/**
|
|
63
103
|
* Helper methods that throw specific validation errors
|
|
64
104
|
*/
|
|
@@ -26,6 +26,7 @@ export interface IChainValidator extends IAddressValidator, ITokenValidator, IAm
|
|
|
26
26
|
validateSourceChain(order: CreateCrossChainOrderParams & { user: string }): Promise<void>;
|
|
27
27
|
validateDestinationChain(order: CreateCrossChainOrderParams): void;
|
|
28
28
|
validateSingleChainOrder(order: CreateSingleChainOrderParams & { user: string }): Promise<void>;
|
|
29
|
+
validateDcaSingleChainOrder(order: CreateDcaSingleChainOrderParams & { user: string }): Promise<void>;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
/**
|
|
@@ -99,3 +100,40 @@ export class SingleChainOrderValidator {
|
|
|
99
100
|
chainValidator.validateSingleChainOrder(order);
|
|
100
101
|
}
|
|
101
102
|
}
|
|
103
|
+
|
|
104
|
+
import type { CreateDcaSingleChainOrderParams } from '../core/orders/dca-single-chain.js';
|
|
105
|
+
|
|
106
|
+
export interface IDcaValidator {
|
|
107
|
+
validateDcaSingleChainOrder(order: CreateDcaSingleChainOrderParams & { user: string }): Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export class DcaSingleChainOrderValidator {
|
|
111
|
+
private readonly commonValidator = new CommonValidator();
|
|
112
|
+
|
|
113
|
+
async validateOrder(order: CreateDcaSingleChainOrderParams & { user: string }): Promise<void> {
|
|
114
|
+
this.commonValidator.validateDeadline(order.deadline);
|
|
115
|
+
|
|
116
|
+
// Validate start time is in the future or current time
|
|
117
|
+
if (order.startTime < Math.floor(Date.now() / 1000)) {
|
|
118
|
+
throw new ValidationError('Start time must be in the future or current time');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Validate intervals
|
|
122
|
+
if (order.totalIntervals <= 0) {
|
|
123
|
+
throw new ValidationError('Total intervals must be greater than 0');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (order.intervalDuration <= 0) {
|
|
127
|
+
throw new ValidationError('Interval duration must be greater than 0');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Validate that the order will complete before deadline
|
|
131
|
+
const estimatedCompletionTime = order.startTime + order.totalIntervals * order.intervalDuration;
|
|
132
|
+
if (estimatedCompletionTime > order.deadline) {
|
|
133
|
+
throw new ValidationError('Order would complete after deadline');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const chainValidator = ValidatorFactory.getValidatorForChain(order.chainId);
|
|
137
|
+
await chainValidator.validateDcaSingleChainOrder(order);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -18,8 +18,8 @@ const LIQUID_SWAP_API_URL = 'https://api.liqd.ag';
|
|
|
18
18
|
|
|
19
19
|
export class LiquidSwapQuoteProvider {
|
|
20
20
|
public async getQuote(liquidSwapParams: LiquidSwapQuoteParams): Promise<LiquidSwapQuoteResponse> {
|
|
21
|
-
const params = {...liquidSwapParams};
|
|
22
|
-
|
|
21
|
+
const params = { ...liquidSwapParams };
|
|
22
|
+
|
|
23
23
|
if (isNativeEvmToken(params.tokenOut)) {
|
|
24
24
|
params.tokenOut = WRAPPED_ETH_ADDRESSES[ChainID.Hyperliquid];
|
|
25
25
|
}
|