naracli 1.0.17 → 1.0.22
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 +101 -114
- package/bin/nara-cli.ts +0 -20
- package/dist/nara-cli.mjs +49930 -2222
- package/index.ts +10 -58
- package/package.json +7 -6
- package/src/cli/commands/quest.ts +8 -7
- package/src/cli/commands/skills.ts +491 -0
- package/src/cli/commands/skillsInstall.ts +793 -0
- package/src/cli/commands/wallet.ts +13 -114
- package/src/cli/commands/zkid.ts +410 -0
- package/src/cli/index.ts +215 -9
- package/src/cli/prompts/searchMultiselect.ts +297 -0
- package/src/cli/types.ts +0 -138
- package/src/cli/utils/transaction.ts +1 -1
- package/src/cli/utils/validation.ts +0 -40
- package/src/cli/utils/wallet.ts +3 -1
- package/src/tests/helpers.ts +78 -0
- package/src/tests/skills.e2e.test.ts +126 -0
- package/src/tests/skills.test.ts +192 -0
- package/src/tests/test_skill.md +18 -0
- package/src/tests/zkid.e2e.test.ts +128 -0
- package/src/tests/zkid.test.ts +153 -0
- package/src/types/snarkjs.d.ts +4 -1
- package/dist/quest/nara_quest.json +0 -534
- package/dist/zk/answer_proof.wasm +0 -0
- package/dist/zk/answer_proof_final.zkey +0 -0
- package/src/cli/commands/config.ts +0 -125
- package/src/cli/commands/migrate.ts +0 -270
- package/src/cli/commands/pool.ts +0 -364
- package/src/cli/commands/swap.ts +0 -349
- package/src/cli/quest/nara_quest.json +0 -534
- package/src/cli/quest/nara_quest_types.ts +0 -540
- package/src/cli/zk/answer_proof.wasm +0 -0
- package/src/cli/zk/answer_proof_final.zkey +0 -0
- package/src/client.ts +0 -96
- package/src/config.ts +0 -132
- package/src/constants.ts +0 -35
- package/src/migrate.ts +0 -222
- package/src/pool.ts +0 -259
- package/src/quest.ts +0 -387
- package/src/swap.ts +0 -608
package/src/config.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { Keypair, PublicKey, Transaction } from "@solana/web3.js";
|
|
2
|
-
import {
|
|
3
|
-
buildCurveWithMarketCap,
|
|
4
|
-
ActivationType,
|
|
5
|
-
CollectFeeMode,
|
|
6
|
-
BaseFeeMode,
|
|
7
|
-
MigrationFeeOption,
|
|
8
|
-
MigrationOption,
|
|
9
|
-
TokenDecimal,
|
|
10
|
-
TokenType,
|
|
11
|
-
TokenUpdateAuthorityOption,
|
|
12
|
-
} from "@meteora-ag/dynamic-bonding-curve-sdk";
|
|
13
|
-
import { NATIVE_MINT } from "@solana/spl-token";
|
|
14
|
-
import { NaraSDK } from "./client";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Options for creating configuration
|
|
18
|
-
*/
|
|
19
|
-
export interface CreateConfigOptions {
|
|
20
|
-
/** Fee claimer wallet address */
|
|
21
|
-
feeClaimer: PublicKey;
|
|
22
|
-
/** Leftover token receiver wallet address */
|
|
23
|
-
leftoverReceiver: PublicKey;
|
|
24
|
-
/** Payer wallet address */
|
|
25
|
-
payer: PublicKey;
|
|
26
|
-
// Curve parameters (all optional with defaults)
|
|
27
|
-
/** Total token supply (default: 1,000,000,000) */
|
|
28
|
-
totalTokenSupply?: number;
|
|
29
|
-
/** Initial market cap (default: 30) */
|
|
30
|
-
initialMarketCap?: number;
|
|
31
|
-
/** Migration market cap threshold (default: 540) */
|
|
32
|
-
migrationMarketCap?: number;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Return type for bonding curve config transaction creation
|
|
37
|
-
*/
|
|
38
|
-
export interface CreateConfigResult {
|
|
39
|
-
/** Config address */
|
|
40
|
-
configAddress: string;
|
|
41
|
-
/** Unsigned transaction */
|
|
42
|
-
transaction: Transaction;
|
|
43
|
-
/** Config keypair (requires partial signature) */
|
|
44
|
-
configKeypair: Keypair;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Create bonding curve config transaction (returns unsigned transaction)
|
|
49
|
-
* @param sdk NaraSDK SDK instance
|
|
50
|
-
* @param options Configuration options
|
|
51
|
-
* @returns Config address, unsigned transaction, and config keypair
|
|
52
|
-
*/
|
|
53
|
-
export async function createConfig(
|
|
54
|
-
sdk: NaraSDK,
|
|
55
|
-
options: CreateConfigOptions
|
|
56
|
-
): Promise<CreateConfigResult> {
|
|
57
|
-
const connection = sdk.getConnection();
|
|
58
|
-
const client = sdk.getClient();
|
|
59
|
-
|
|
60
|
-
// Generate new config keypair
|
|
61
|
-
const config = Keypair.generate();
|
|
62
|
-
|
|
63
|
-
// Build bonding curve configuration
|
|
64
|
-
const curveConfig = buildCurveWithMarketCap({
|
|
65
|
-
totalTokenSupply: options.totalTokenSupply ?? 1_000_000_000, // Total token supply
|
|
66
|
-
initialMarketCap: options.initialMarketCap ?? 30, // Initial market cap
|
|
67
|
-
migrationMarketCap: options.migrationMarketCap ?? 540, // Migration market cap threshold
|
|
68
|
-
migrationOption: MigrationOption.MET_DAMM_V2, // Migration option: use Meteora DAMM V2
|
|
69
|
-
tokenBaseDecimal: TokenDecimal.SIX, // Base token decimals: 6
|
|
70
|
-
tokenQuoteDecimal: TokenDecimal.NINE, // Quote token decimals: 9 (SOL)
|
|
71
|
-
// Locked vesting parameters
|
|
72
|
-
lockedVestingParams: {
|
|
73
|
-
totalLockedVestingAmount: 0, // Total locked vesting amount
|
|
74
|
-
numberOfVestingPeriod: 0, // Number of vesting periods
|
|
75
|
-
cliffUnlockAmount: 0, // Cliff unlock amount
|
|
76
|
-
totalVestingDuration: 0, // Total vesting duration
|
|
77
|
-
cliffDurationFromMigrationTime: 0, // Cliff duration from migration time
|
|
78
|
-
},
|
|
79
|
-
// Base fee parameters
|
|
80
|
-
baseFeeParams: {
|
|
81
|
-
baseFeeMode: BaseFeeMode.FeeSchedulerLinear, // Fee mode: linear scheduler
|
|
82
|
-
feeSchedulerParam: {
|
|
83
|
-
startingFeeBps: 100, // Starting fee (basis points): 1%
|
|
84
|
-
endingFeeBps: 100, // Ending fee (basis points): 1%
|
|
85
|
-
numberOfPeriod: 0, // Number of periods
|
|
86
|
-
totalDuration: 0, // Total duration
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
dynamicFeeEnabled: true, // Enable dynamic fees
|
|
90
|
-
activationType: ActivationType.Slot, // Activation type: slot-based
|
|
91
|
-
collectFeeMode: CollectFeeMode.QuoteToken, // Fee collection mode: quote token
|
|
92
|
-
migrationFeeOption: MigrationFeeOption.FixedBps25, // Migration fee option: fixed 1%
|
|
93
|
-
tokenType: TokenType.SPL, // Token type: SPL token
|
|
94
|
-
partnerLiquidityPercentage: 0, // Partner liquidity percentage
|
|
95
|
-
creatorLiquidityPercentage: 0, // Creator liquidity percentage
|
|
96
|
-
partnerPermanentLockedLiquidityPercentage: 100, // Partner permanent locked liquidity: 100%
|
|
97
|
-
creatorPermanentLockedLiquidityPercentage: 0, // Creator permanent locked liquidity: 0%
|
|
98
|
-
creatorTradingFeePercentage: 0, // Creator trading fee percentage: 0%
|
|
99
|
-
leftover: 0, // Leftover token amount
|
|
100
|
-
tokenUpdateAuthority: TokenUpdateAuthorityOption.Immutable, // Token update authority: immutable
|
|
101
|
-
// Migration fee
|
|
102
|
-
migrationFee: {
|
|
103
|
-
feePercentage: 0, // Fee percentage
|
|
104
|
-
creatorFeePercentage: 0, // Creator fee percentage
|
|
105
|
-
},
|
|
106
|
-
poolCreationFee: 0.1, // Pool creation fee
|
|
107
|
-
enableFirstSwapWithMinFee: true, // Enable first swap with minimum fee
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Create config transaction
|
|
111
|
-
const transaction = await client.partner.createConfig({
|
|
112
|
-
config: config.publicKey, // Config public key
|
|
113
|
-
feeClaimer: options.feeClaimer, // Fee claimer
|
|
114
|
-
leftoverReceiver: options.leftoverReceiver, // Leftover receiver
|
|
115
|
-
payer: options.payer, // Payer
|
|
116
|
-
quoteMint: NATIVE_MINT, // Quote mint: native SOL
|
|
117
|
-
...curveConfig, // Curve config parameters
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// Get latest blockhash
|
|
121
|
-
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
122
|
-
transaction.recentBlockhash = blockhash;
|
|
123
|
-
transaction.feePayer = options.payer;
|
|
124
|
-
// Config account partial signature
|
|
125
|
-
transaction.partialSign(config);
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
configAddress: config.publicKey.toBase58(), // Config address
|
|
129
|
-
transaction, // Unsigned transaction (already has config's partial signature)
|
|
130
|
-
configKeypair: config, // Config keypair
|
|
131
|
-
};
|
|
132
|
-
}
|
package/src/constants.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SDK and CLI default constants
|
|
3
|
-
*
|
|
4
|
-
* Priority for all values: CLI flag > env variable > default value
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Default RPC URL for Nara testnet
|
|
9
|
-
*/
|
|
10
|
-
export const DEFAULT_RPC_URL =
|
|
11
|
-
process.env.RPC_URL || "https://mainnet-api.nara.build/";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Default bonding curve config address
|
|
15
|
-
*/
|
|
16
|
-
export const DEFAULT_DBC_CONFIG_ADDRESS =
|
|
17
|
-
process.env.DBC_CONFIG_ADDRESS || "";
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Default wallet path
|
|
21
|
-
*/
|
|
22
|
-
export const DEFAULT_WALLET_PATH =
|
|
23
|
-
process.env.WALLET_PATH || "~/.config/nara/id.json";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Default quest relay URL
|
|
27
|
-
*/
|
|
28
|
-
export const DEFAULT_QUEST_RELAY_URL =
|
|
29
|
-
process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Quest program ID
|
|
33
|
-
*/
|
|
34
|
-
export const DEFAULT_QUEST_PROGRAM_ID =
|
|
35
|
-
process.env.QUEST_PROGRAM_ID || "Quest11111111111111111111111111111111111111";
|
package/src/migrate.ts
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PublicKey,
|
|
3
|
-
Transaction,
|
|
4
|
-
Keypair,
|
|
5
|
-
VersionedTransaction,
|
|
6
|
-
} from "@solana/web3.js";
|
|
7
|
-
import BN from "bn.js";
|
|
8
|
-
import { NaraSDK } from "./client";
|
|
9
|
-
import { DAMM_V2_MIGRATION_FEE_ADDRESS } from "@meteora-ag/dynamic-bonding-curve-sdk";
|
|
10
|
-
|
|
11
|
-
export interface MigrateToDAMMV2Params {
|
|
12
|
-
/** Token address (baseMint) */
|
|
13
|
-
tokenAddress: string;
|
|
14
|
-
/** Payer */
|
|
15
|
-
payer: PublicKey;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface MigrateToDAMMV2Result {
|
|
19
|
-
/** Migration transaction (returns VersionedTransaction if ALT is configured) */
|
|
20
|
-
transaction: Transaction | VersionedTransaction;
|
|
21
|
-
/** First Position NFT keypair (requires signature) */
|
|
22
|
-
firstPositionNftKeypair: Keypair;
|
|
23
|
-
/** Second Position NFT keypair (requires signature) */
|
|
24
|
-
secondPositionNftKeypair: Keypair;
|
|
25
|
-
/** Pool address */
|
|
26
|
-
poolAddress: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface CreateLockerParams {
|
|
30
|
-
/** Token address (baseMint) */
|
|
31
|
-
tokenAddress: string;
|
|
32
|
-
/** Payer */
|
|
33
|
-
payer: PublicKey;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface CreateLockerResult {
|
|
37
|
-
/** Locker creation transaction (returns VersionedTransaction if ALT is configured) */
|
|
38
|
-
transaction: Transaction | VersionedTransaction;
|
|
39
|
-
/** Pool address */
|
|
40
|
-
poolAddress: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Launch token pool to DAMM V2 (graduation)
|
|
45
|
-
*
|
|
46
|
-
* Call this function to migrate the pool to DAMM V2 after the bonding curve is complete (100%)
|
|
47
|
-
*
|
|
48
|
-
* Notes:
|
|
49
|
-
* - dammConfig address is automatically derived from pool config's migrationFeeOption
|
|
50
|
-
* - If token has locked vesting parameters, may need to call createLocker() first
|
|
51
|
-
* - Requires signatures from three keypairs: payer, firstPositionNftKeypair, secondPositionNftKeypair
|
|
52
|
-
*
|
|
53
|
-
* @param sdk NaraSDK SDK instance
|
|
54
|
-
* @param params Migration parameters
|
|
55
|
-
* @returns Migration transaction, Position NFT keypairs, and pool address
|
|
56
|
-
*/
|
|
57
|
-
export async function migrateToDAMMV2(
|
|
58
|
-
sdk: NaraSDK,
|
|
59
|
-
params: MigrateToDAMMV2Params
|
|
60
|
-
): Promise<MigrateToDAMMV2Result> {
|
|
61
|
-
const connection = sdk.getConnection();
|
|
62
|
-
const client = sdk.getClient();
|
|
63
|
-
const tokenPubkey = new PublicKey(params.tokenAddress);
|
|
64
|
-
|
|
65
|
-
// Get pool account
|
|
66
|
-
const poolAccount = await client.state.getPoolByBaseMint(tokenPubkey);
|
|
67
|
-
if (!poolAccount) {
|
|
68
|
-
throw new Error(`Pool not found for token: ${params.tokenAddress}`);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Check if pool has already been migrated
|
|
72
|
-
if (poolAccount.account.isMigrated) {
|
|
73
|
-
throw new Error("Pool has already been migrated");
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Get pool config and read migrationFeeOption
|
|
77
|
-
const virtualPool = poolAccount.account;
|
|
78
|
-
const poolConfig = await client.state.getPoolConfig(virtualPool.config);
|
|
79
|
-
|
|
80
|
-
// Get corresponding config address from DAMM_V2_MIGRATION_FEE_ADDRESS array
|
|
81
|
-
// Using 'any' type since poolConfig's migrationFeeOption is IDL-derived
|
|
82
|
-
const migrationFeeOption = (poolConfig as any).migrationFeeOption || 0;
|
|
83
|
-
const dammConfig = DAMM_V2_MIGRATION_FEE_ADDRESS[migrationFeeOption];
|
|
84
|
-
|
|
85
|
-
if (!dammConfig) {
|
|
86
|
-
throw new Error(
|
|
87
|
-
`Invalid migration fee option: ${migrationFeeOption}. Cannot determine DAMM config address.`
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Note: If the pool has locked vesting parameters, a locker might need to be created first
|
|
92
|
-
// Use createLocker() if the migration fails due to missing locker
|
|
93
|
-
|
|
94
|
-
// Call SDK's migrateToDammV2 method
|
|
95
|
-
const result = await client.migration.migrateToDammV2({
|
|
96
|
-
payer: params.payer,
|
|
97
|
-
virtualPool: poolAccount.publicKey,
|
|
98
|
-
dammConfig,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Get latest blockhash
|
|
102
|
-
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
103
|
-
result.transaction.recentBlockhash = blockhash;
|
|
104
|
-
result.transaction.feePayer = params.payer;
|
|
105
|
-
|
|
106
|
-
// Compile transaction with ALT if configured
|
|
107
|
-
const compiledTx = await sdk.compileTransactionWithALT(
|
|
108
|
-
result.transaction,
|
|
109
|
-
params.payer
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
transaction: compiledTx,
|
|
114
|
-
firstPositionNftKeypair: result.firstPositionNftKeypair,
|
|
115
|
-
secondPositionNftKeypair: result.secondPositionNftKeypair,
|
|
116
|
-
poolAddress: poolAccount.publicKey.toBase58(),
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Create Locker (for token pools with locked vesting parameters)
|
|
122
|
-
*
|
|
123
|
-
* If the token pool has locked vesting parameters (amountPerPeriod > 0 or cliffUnlockAmount > 0),
|
|
124
|
-
* a locker must be created before migrating to DAMM V2
|
|
125
|
-
*
|
|
126
|
-
* @param sdk NaraSDK SDK instance
|
|
127
|
-
* @param params Locker parameters
|
|
128
|
-
* @returns Locker creation transaction and pool address
|
|
129
|
-
*/
|
|
130
|
-
export async function createLocker(
|
|
131
|
-
sdk: NaraSDK,
|
|
132
|
-
params: CreateLockerParams
|
|
133
|
-
): Promise<CreateLockerResult> {
|
|
134
|
-
const connection = sdk.getConnection();
|
|
135
|
-
const client = sdk.getClient();
|
|
136
|
-
const tokenPubkey = new PublicKey(params.tokenAddress);
|
|
137
|
-
|
|
138
|
-
// Get pool account
|
|
139
|
-
const poolAccount = await client.state.getPoolByBaseMint(tokenPubkey);
|
|
140
|
-
if (!poolAccount) {
|
|
141
|
-
throw new Error(`Pool not found for token: ${params.tokenAddress}`);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Create locker
|
|
145
|
-
const transaction = await client.migration.createLocker({
|
|
146
|
-
payer: params.payer,
|
|
147
|
-
virtualPool: poolAccount.publicKey,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
// Get latest blockhash
|
|
151
|
-
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
152
|
-
transaction.recentBlockhash = blockhash;
|
|
153
|
-
transaction.feePayer = params.payer;
|
|
154
|
-
|
|
155
|
-
// Compile transaction with ALT if configured
|
|
156
|
-
const compiledTx = await sdk.compileTransactionWithALT(
|
|
157
|
-
transaction,
|
|
158
|
-
params.payer
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
return {
|
|
162
|
-
transaction: compiledTx,
|
|
163
|
-
poolAddress: poolAccount.publicKey.toBase58(),
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Check if pool can be launched to DAMM V2
|
|
169
|
-
*
|
|
170
|
-
* @param sdk NaraSDK SDK instance
|
|
171
|
-
* @param tokenAddress Token address (baseMint)
|
|
172
|
-
* @returns Whether pool can be launched
|
|
173
|
-
*/
|
|
174
|
-
export async function canMigrate(
|
|
175
|
-
sdk: NaraSDK,
|
|
176
|
-
tokenAddress: string
|
|
177
|
-
): Promise<{
|
|
178
|
-
canMigrate: boolean;
|
|
179
|
-
reason?: string;
|
|
180
|
-
progress: number;
|
|
181
|
-
}> {
|
|
182
|
-
const client = sdk.getClient();
|
|
183
|
-
const tokenPubkey = new PublicKey(tokenAddress);
|
|
184
|
-
|
|
185
|
-
// Get pool account
|
|
186
|
-
const poolAccount = await client.state.getPoolByBaseMint(tokenPubkey);
|
|
187
|
-
if (!poolAccount) {
|
|
188
|
-
return {
|
|
189
|
-
canMigrate: false,
|
|
190
|
-
reason: "Pool not found",
|
|
191
|
-
progress: 0,
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Check if already migrated
|
|
196
|
-
if (poolAccount.account.isMigrated) {
|
|
197
|
-
return {
|
|
198
|
-
canMigrate: false,
|
|
199
|
-
reason: "Pool has already been migrated",
|
|
200
|
-
progress: 1,
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Get curve progress
|
|
205
|
-
const progress = await client.state.getPoolCurveProgress(
|
|
206
|
-
poolAccount.publicKey
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
// Check if 100% complete
|
|
210
|
-
if (progress >= 1.0) {
|
|
211
|
-
return {
|
|
212
|
-
canMigrate: true,
|
|
213
|
-
progress,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
canMigrate: false,
|
|
219
|
-
reason: `Curve not complete. Current progress: ${(progress * 100).toFixed(2)}%`,
|
|
220
|
-
progress,
|
|
221
|
-
};
|
|
222
|
-
}
|
package/src/pool.ts
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Keypair,
|
|
3
|
-
PublicKey,
|
|
4
|
-
Transaction,
|
|
5
|
-
VersionedTransaction,
|
|
6
|
-
} from "@solana/web3.js";
|
|
7
|
-
import { NATIVE_MINT } from "@solana/spl-token";
|
|
8
|
-
import BN from "bn.js";
|
|
9
|
-
import { deriveDbcPoolAddress } from "@meteora-ag/dynamic-bonding-curve-sdk";
|
|
10
|
-
import { NaraSDK } from "./client";
|
|
11
|
-
|
|
12
|
-
export interface CreatePoolParams {
|
|
13
|
-
name: string;
|
|
14
|
-
symbol: string;
|
|
15
|
-
uri: string;
|
|
16
|
-
configAddress: string;
|
|
17
|
-
payer: PublicKey;
|
|
18
|
-
poolCreator: PublicKey;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface CreatePoolResult {
|
|
22
|
-
/** Pool address */
|
|
23
|
-
poolAddress: string;
|
|
24
|
-
/** Token address (baseMint) */
|
|
25
|
-
baseMint: string;
|
|
26
|
-
/** Unsigned transaction for pool creation (returns VersionedTransaction if ALT is configured) */
|
|
27
|
-
transaction: Transaction | VersionedTransaction;
|
|
28
|
-
/** baseMint keypair (requires signature) */
|
|
29
|
-
baseMintKeypair: Keypair;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface CreatePoolWithFirstBuyParams extends CreatePoolParams {
|
|
33
|
-
/** Initial buy amount in SOL */
|
|
34
|
-
initialBuyAmountSOL: number;
|
|
35
|
-
/** Buyer (defaults to payer) */
|
|
36
|
-
buyer?: PublicKey;
|
|
37
|
-
/** Token receiver (defaults to buyer) */
|
|
38
|
-
receiver?: PublicKey;
|
|
39
|
-
/** Slippage in basis points (default 100 = 1%) */
|
|
40
|
-
slippageBps?: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface CreatePoolWithFirstBuyResult {
|
|
44
|
-
/** Pool address */
|
|
45
|
-
poolAddress: string;
|
|
46
|
-
/** Token address (baseMint) */
|
|
47
|
-
baseMint: string;
|
|
48
|
-
/** Pool creation transaction (returns VersionedTransaction if ALT is configured) */
|
|
49
|
-
createPoolTx: Transaction | VersionedTransaction;
|
|
50
|
-
/** First buy transaction (returns VersionedTransaction if ALT is configured) */
|
|
51
|
-
firstBuyTx: Transaction | VersionedTransaction;
|
|
52
|
-
/** baseMint keypair (requires signature) */
|
|
53
|
-
baseMintKeypair: Keypair;
|
|
54
|
-
/** Buy information */
|
|
55
|
-
buyInfo: {
|
|
56
|
-
amountIn: string;
|
|
57
|
-
minimumAmountOut: string;
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Create token pool transaction (returns unsigned transaction)
|
|
63
|
-
*
|
|
64
|
-
* Note: If you want to make an initial buy, wait for this transaction to confirm
|
|
65
|
-
* before using the buyToken() function
|
|
66
|
-
*
|
|
67
|
-
* @param sdk NaraSDK SDK instance
|
|
68
|
-
* @param params Pool parameters
|
|
69
|
-
* @returns Pool address, token address, unsigned transaction, and baseMint keypair
|
|
70
|
-
*/
|
|
71
|
-
export async function createPool(
|
|
72
|
-
sdk: NaraSDK,
|
|
73
|
-
params: CreatePoolParams
|
|
74
|
-
): Promise<CreatePoolResult> {
|
|
75
|
-
const connection = sdk.getConnection();
|
|
76
|
-
const client = sdk.getClient();
|
|
77
|
-
|
|
78
|
-
const baseMint = Keypair.generate();
|
|
79
|
-
const configPubkey = new PublicKey(params.configAddress);
|
|
80
|
-
|
|
81
|
-
// Create pool transaction
|
|
82
|
-
const createPoolTx = await client.pool.createPool({
|
|
83
|
-
baseMint: baseMint.publicKey,
|
|
84
|
-
config: configPubkey,
|
|
85
|
-
name: params.name,
|
|
86
|
-
symbol: params.symbol,
|
|
87
|
-
uri: params.uri,
|
|
88
|
-
payer: params.payer,
|
|
89
|
-
poolCreator: params.poolCreator,
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Get latest blockhash
|
|
93
|
-
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
94
|
-
createPoolTx.recentBlockhash = blockhash;
|
|
95
|
-
createPoolTx.feePayer = params.payer;
|
|
96
|
-
|
|
97
|
-
// Derive pool address
|
|
98
|
-
const poolPubkey = deriveDbcPoolAddress(
|
|
99
|
-
NATIVE_MINT,
|
|
100
|
-
baseMint.publicKey,
|
|
101
|
-
configPubkey
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
// Compile transaction with ALT if configured
|
|
105
|
-
const compiledTx = await sdk.compileTransactionWithALT(
|
|
106
|
-
createPoolTx,
|
|
107
|
-
params.payer
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
poolAddress: poolPubkey.toBase58(),
|
|
112
|
-
baseMint: baseMint.publicKey.toBase58(),
|
|
113
|
-
transaction: compiledTx,
|
|
114
|
-
baseMintKeypair: baseMint,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Create token pool and perform first buy (one-step completion)
|
|
120
|
-
*
|
|
121
|
-
* Uses SDK's createPoolWithFirstBuy method to complete creation and buy in one transaction
|
|
122
|
-
*
|
|
123
|
-
* @param sdk NaraSDK SDK instance
|
|
124
|
-
* @param params Pool and buy parameters
|
|
125
|
-
* @returns Pool address, token address, unsigned transactions, and baseMint keypair
|
|
126
|
-
*/
|
|
127
|
-
export async function createPoolWithFirstBuy(
|
|
128
|
-
sdk: NaraSDK,
|
|
129
|
-
params: CreatePoolWithFirstBuyParams
|
|
130
|
-
): Promise<CreatePoolWithFirstBuyResult> {
|
|
131
|
-
const connection = sdk.getConnection();
|
|
132
|
-
const client = sdk.getClient();
|
|
133
|
-
|
|
134
|
-
const baseMint = Keypair.generate();
|
|
135
|
-
const configPubkey = new PublicKey(params.configAddress);
|
|
136
|
-
const buyer = params.buyer ?? params.payer;
|
|
137
|
-
const receiver = params.receiver ?? buyer;
|
|
138
|
-
|
|
139
|
-
// Calculate buy amount
|
|
140
|
-
const buyAmount = new BN(params.initialBuyAmountSOL * 1e9); // SOL to lamports
|
|
141
|
-
const slippageBps = params.slippageBps ?? 100;
|
|
142
|
-
|
|
143
|
-
// For first buy, use conservative minimumAmountOut
|
|
144
|
-
// Set to 0 since this is the first buy with optimal price
|
|
145
|
-
const minimumAmountOut = new BN(0);
|
|
146
|
-
|
|
147
|
-
// Use SDK's createPoolWithFirstBuy method
|
|
148
|
-
const result = await client.pool.createPoolWithFirstBuy({
|
|
149
|
-
createPoolParam: {
|
|
150
|
-
baseMint: baseMint.publicKey,
|
|
151
|
-
config: configPubkey,
|
|
152
|
-
name: params.name,
|
|
153
|
-
symbol: params.symbol,
|
|
154
|
-
uri: params.uri,
|
|
155
|
-
payer: params.payer,
|
|
156
|
-
poolCreator: params.poolCreator,
|
|
157
|
-
},
|
|
158
|
-
firstBuyParam: {
|
|
159
|
-
buyer,
|
|
160
|
-
receiver,
|
|
161
|
-
buyAmount,
|
|
162
|
-
minimumAmountOut,
|
|
163
|
-
referralTokenAccount: null,
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// Get latest blockhash
|
|
168
|
-
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
169
|
-
|
|
170
|
-
// Combine two transactions into one
|
|
171
|
-
const combinedTx = new Transaction();
|
|
172
|
-
|
|
173
|
-
// Add pool creation instructions
|
|
174
|
-
combinedTx.add(...result.createPoolTx.instructions);
|
|
175
|
-
|
|
176
|
-
// If first buy transaction exists, add buy instructions
|
|
177
|
-
if (result.swapBuyTx) {
|
|
178
|
-
combinedTx.add(...result.swapBuyTx.instructions);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Set transaction metadata
|
|
182
|
-
combinedTx.recentBlockhash = blockhash;
|
|
183
|
-
combinedTx.feePayer = params.payer;
|
|
184
|
-
|
|
185
|
-
// Derive pool address
|
|
186
|
-
const poolPubkey = deriveDbcPoolAddress(
|
|
187
|
-
NATIVE_MINT,
|
|
188
|
-
baseMint.publicKey,
|
|
189
|
-
configPubkey
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
// Compile transaction with ALT if configured
|
|
193
|
-
const compiledTx = await sdk.compileTransactionWithALT(
|
|
194
|
-
combinedTx,
|
|
195
|
-
params.payer
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
poolAddress: poolPubkey.toBase58(),
|
|
200
|
-
baseMint: baseMint.publicKey.toBase58(),
|
|
201
|
-
createPoolTx: compiledTx, // Return combined transaction
|
|
202
|
-
firstBuyTx: compiledTx, // Same as createPoolTx since they are combined
|
|
203
|
-
baseMintKeypair: baseMint,
|
|
204
|
-
buyInfo: {
|
|
205
|
-
amountIn: buyAmount.toString(),
|
|
206
|
-
minimumAmountOut: minimumAmountOut.toString(),
|
|
207
|
-
},
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Get pool information
|
|
213
|
-
* @param sdk NaraSDK SDK instance
|
|
214
|
-
* @param tokenAddress Token address (baseMint)
|
|
215
|
-
* @returns Pool information
|
|
216
|
-
*/
|
|
217
|
-
export async function getPoolInfo(sdk: NaraSDK, tokenAddress: string) {
|
|
218
|
-
const client = sdk.getClient();
|
|
219
|
-
const tokenPubkey = new PublicKey(tokenAddress);
|
|
220
|
-
|
|
221
|
-
// Get pool by token (baseMint) address
|
|
222
|
-
const poolAccount = await client.state.getPoolByBaseMint(tokenPubkey);
|
|
223
|
-
if (!poolAccount) {
|
|
224
|
-
throw new Error(`Pool not found for token: ${tokenAddress}`);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return {
|
|
228
|
-
...poolAccount.account,
|
|
229
|
-
poolAddress: poolAccount.publicKey.toBase58(),
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Get pool curve progress
|
|
235
|
-
* @param sdk NaraSDK SDK instance
|
|
236
|
-
* @param tokenAddress Token address (baseMint)
|
|
237
|
-
* @returns Curve progress information
|
|
238
|
-
*/
|
|
239
|
-
export async function getPoolProgress(sdk: NaraSDK, tokenAddress: string) {
|
|
240
|
-
const client = sdk.getClient();
|
|
241
|
-
const tokenPubkey = new PublicKey(tokenAddress);
|
|
242
|
-
|
|
243
|
-
// Get pool by token (baseMint) address
|
|
244
|
-
const poolAccount = await client.state.getPoolByBaseMint(tokenPubkey);
|
|
245
|
-
if (!poolAccount) {
|
|
246
|
-
throw new Error(`Pool not found for token: ${tokenAddress}`);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const progress = await client.state.getPoolCurveProgress(
|
|
250
|
-
poolAccount.publicKey
|
|
251
|
-
);
|
|
252
|
-
const pool = poolAccount.account;
|
|
253
|
-
|
|
254
|
-
return {
|
|
255
|
-
progress,
|
|
256
|
-
quoteReserve: pool.quoteReserve?.toString() ?? "0",
|
|
257
|
-
isMigrated: pool.isMigrated ?? false,
|
|
258
|
-
};
|
|
259
|
-
}
|