@glamsystems/glam-cli 0.1.34 → 0.1.36
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/main.js +261 -36
- package/package.json +2 -2
package/main.js
CHANGED
|
@@ -275,12 +275,15 @@ class StateModel extends StateIdlModel {
|
|
|
275
275
|
// @ts-ignore
|
|
276
276
|
const value = Object.values(param.value)[0].val;
|
|
277
277
|
// Ledger is a mint param but we store it on the state model
|
|
278
|
-
if (
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
278
|
+
if (name === "ledger") {
|
|
279
|
+
stateModel["ledger"] = value;
|
|
280
|
+
}
|
|
281
|
+
else if (name === "redemptionNotifyAndSettle") {
|
|
282
|
+
mintIdlModel["notifyAndSettle"] = value;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
mintIdlModel[name] = value;
|
|
282
286
|
}
|
|
283
|
-
mintIdlModel[name] = value;
|
|
284
287
|
});
|
|
285
288
|
if (openfundsMetadataAccount) {
|
|
286
289
|
const mintOpenfundsFields = {};
|
|
@@ -763,7 +766,7 @@ const blockhash_1 = __webpack_require__(20);
|
|
|
763
766
|
const glamPDAs_1 = __webpack_require__(21);
|
|
764
767
|
const DEFAULT_PRIORITY_FEE = 10000; // microLamports
|
|
765
768
|
const LOOKUP_TABLES = [
|
|
766
|
-
new web3_js_1.PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2"), // kamino
|
|
769
|
+
new web3_js_1.PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2"), // kamino lending
|
|
767
770
|
new web3_js_1.PublicKey("D9cnvzswDikQDf53k4HpQ3KJ9y1Fv3HGGDFYMXnK5T6c"), // drift
|
|
768
771
|
new web3_js_1.PublicKey("EiWSskK5HXnBTptiS5DH6gpAJRVNQ3cAhTKBGaiaysAb"), // drift
|
|
769
772
|
];
|
|
@@ -1353,6 +1356,7 @@ exports.BaseClient = BaseClient;
|
|
|
1353
1356
|
|
|
1354
1357
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1355
1358
|
exports.setsAreEqual = exports.getSimulationResult = exports.parseMeteoraPosition = exports.fetchMeteoraPositions = exports.getStakeAccountsWithStates = exports.findStakeAccounts = void 0;
|
|
1359
|
+
exports.getProgramAccountsV2 = getProgramAccountsV2;
|
|
1356
1360
|
exports.getTokenAccountsByOwner = getTokenAccountsByOwner;
|
|
1357
1361
|
exports.getSolAndTokenBalances = getSolAndTokenBalances;
|
|
1358
1362
|
exports.parseProgramLogs = parseProgramLogs;
|
|
@@ -1362,6 +1366,78 @@ const dlmm_1 = __webpack_require__(15);
|
|
|
1362
1366
|
const anchor_1 = __webpack_require__(4);
|
|
1363
1367
|
const glamExports_1 = __webpack_require__(3);
|
|
1364
1368
|
const spl_token_1 = __webpack_require__(8);
|
|
1369
|
+
// Example response from Helius:
|
|
1370
|
+
// {
|
|
1371
|
+
// "jsonrpc": "2.0",
|
|
1372
|
+
// "id": "1",
|
|
1373
|
+
// "result": {
|
|
1374
|
+
// "accounts": [
|
|
1375
|
+
// {
|
|
1376
|
+
// "pubkey": "CxELquR1gPP8wHe33gZ4QxqGB3sZ9RSwsJ2KshVewkFY",
|
|
1377
|
+
// "account": {
|
|
1378
|
+
// "lamports": 15298080,
|
|
1379
|
+
// "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
|
|
1380
|
+
// "data": [
|
|
1381
|
+
// "2R9jLfiAQ9bgdcw6h8s44439",
|
|
1382
|
+
// "base64"
|
|
1383
|
+
// ],
|
|
1384
|
+
// "executable": false,
|
|
1385
|
+
// "rentEpoch": 28,
|
|
1386
|
+
// "space": 165
|
|
1387
|
+
// }
|
|
1388
|
+
// }
|
|
1389
|
+
// ],
|
|
1390
|
+
// "paginationKey": "8WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
|
|
1391
|
+
// "totalResults": 25000
|
|
1392
|
+
// }
|
|
1393
|
+
// }
|
|
1394
|
+
async function getProgramAccountsV2(programId, limit = 100, filters) {
|
|
1395
|
+
const heliusApiKey = process.env.NEXT_PUBLIC_HELIUS_API_KEY || process.env.HELIUS_API_KEY;
|
|
1396
|
+
let allAccounts = [];
|
|
1397
|
+
let paginationKey = null;
|
|
1398
|
+
let encoding = "base64";
|
|
1399
|
+
do {
|
|
1400
|
+
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${heliusApiKey}`, {
|
|
1401
|
+
method: "POST",
|
|
1402
|
+
headers: { "Content-Type": "application/json" },
|
|
1403
|
+
body: JSON.stringify({
|
|
1404
|
+
jsonrpc: "2.0",
|
|
1405
|
+
id: "1",
|
|
1406
|
+
method: "getProgramAccountsV2",
|
|
1407
|
+
params: [
|
|
1408
|
+
programId.toBase58(),
|
|
1409
|
+
{
|
|
1410
|
+
encoding,
|
|
1411
|
+
filters,
|
|
1412
|
+
limit,
|
|
1413
|
+
...(paginationKey && { paginationKey }),
|
|
1414
|
+
},
|
|
1415
|
+
],
|
|
1416
|
+
}),
|
|
1417
|
+
});
|
|
1418
|
+
const data = await response.json();
|
|
1419
|
+
data.result.accounts.forEach(({ pubkey, account }) => {
|
|
1420
|
+
const [acountData, encoding] = account.data;
|
|
1421
|
+
let decodedData;
|
|
1422
|
+
if (encoding === "base64") {
|
|
1423
|
+
decodedData = Buffer.from(acountData, "base64");
|
|
1424
|
+
}
|
|
1425
|
+
if (!decodedData) {
|
|
1426
|
+
throw new Error("Failed to decode base64 account data");
|
|
1427
|
+
}
|
|
1428
|
+
allAccounts.push({
|
|
1429
|
+
pubkey: new web3_js_1.PublicKey(pubkey),
|
|
1430
|
+
account: {
|
|
1431
|
+
...account,
|
|
1432
|
+
owner: new web3_js_1.PublicKey(account.owner),
|
|
1433
|
+
data: decodedData,
|
|
1434
|
+
},
|
|
1435
|
+
});
|
|
1436
|
+
});
|
|
1437
|
+
paginationKey = data.result.paginationKey;
|
|
1438
|
+
} while (paginationKey);
|
|
1439
|
+
return allAccounts;
|
|
1440
|
+
}
|
|
1365
1441
|
/**
|
|
1366
1442
|
* Fetches all the token accounts owned by the specified pubkey.
|
|
1367
1443
|
*/
|
|
@@ -5313,7 +5389,8 @@ class StakingClient {
|
|
|
5313
5389
|
const { programId: stakePoolProgram, poolMint, withdrawAuthority, feeAccount, tokenProgramId: tokenProgram, validatorList, reserveStake, } = await this.getStakePoolAccountData(stakePool);
|
|
5314
5390
|
const poolTokensFrom = this.base.getVaultAta(poolMint, tokenProgram);
|
|
5315
5391
|
// The reserve stake account should NOT be used for withdrawals unless we have no other options.
|
|
5316
|
-
|
|
5392
|
+
// And only active validator stake accounts should be used.
|
|
5393
|
+
const validatorStakeCandidates = (await (0, helpers_1.getStakeAccountsWithStates)(this.base.provider.connection, withdrawAuthority)).filter((s) => !s.address.equals(reserveStake) && s.state === "active");
|
|
5317
5394
|
const validatorStakeAccount = validatorStakeCandidates.length === 0
|
|
5318
5395
|
? reserveStake
|
|
5319
5396
|
: validatorStakeCandidates[0].address;
|
|
@@ -5823,7 +5900,6 @@ class MintClient {
|
|
|
5823
5900
|
});
|
|
5824
5901
|
}
|
|
5825
5902
|
async update(mintModel, txOptions = {}) {
|
|
5826
|
-
// @ts-ignore
|
|
5827
5903
|
const tx = await this.base.program.methods
|
|
5828
5904
|
.updateMint(0, new models_1.MintIdlModel(mintModel))
|
|
5829
5905
|
.accounts({
|
|
@@ -5856,6 +5932,19 @@ class MintClient {
|
|
|
5856
5932
|
const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
|
|
5857
5933
|
return await this.base.sendAndConfirm(vTx);
|
|
5858
5934
|
}
|
|
5935
|
+
async setPermissionlessFulfill(enabled, txOptions = {}) {
|
|
5936
|
+
const stateModel = await this.base.fetchStateModel();
|
|
5937
|
+
const notifyAndSettle = stateModel.mints?.[0]?.notifyAndSettle;
|
|
5938
|
+
if (!notifyAndSettle) {
|
|
5939
|
+
throw new Error("Mint does not have notifyAndSettle configured.");
|
|
5940
|
+
}
|
|
5941
|
+
return await this.update({
|
|
5942
|
+
notifyAndSettle: {
|
|
5943
|
+
...notifyAndSettle,
|
|
5944
|
+
permissionlessFulfillment: enabled,
|
|
5945
|
+
},
|
|
5946
|
+
}, txOptions);
|
|
5947
|
+
}
|
|
5859
5948
|
async closeMintIx() {
|
|
5860
5949
|
return await this.base.program.methods
|
|
5861
5950
|
.closeMint(0)
|
|
@@ -6087,6 +6176,7 @@ const borsh = tslib_1.__importStar(__webpack_require__(25));
|
|
|
6087
6176
|
const spl_token_1 = __webpack_require__(8);
|
|
6088
6177
|
const constants_1 = __webpack_require__(10);
|
|
6089
6178
|
const kaminoLayouts_1 = __webpack_require__(36);
|
|
6179
|
+
const helpers_1 = __webpack_require__(14);
|
|
6090
6180
|
const DEFAULT_OBLIGATION_ARGS = { tag: 0, id: 0 };
|
|
6091
6181
|
const EVENT_AUTHORITY = new web3_js_1.PublicKey("24tHwQyJJ9akVXxnvkekGfAoeUJXXS7mE6kQNioNySsK");
|
|
6092
6182
|
class KaminoLendingClient {
|
|
@@ -6907,19 +6997,30 @@ class KaminoFarmClient {
|
|
|
6907
6997
|
this.farmVaultsAuthority = (farm) => web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("authority"), farm.toBuffer()], constants_1.KAMINO_FARM_PROGRAM)[0];
|
|
6908
6998
|
this.rewardsTreasuryVault = (globalConfig, mint) => web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("tvault"), globalConfig.toBuffer(), mint.toBuffer()], constants_1.KAMINO_FARM_PROGRAM)[0];
|
|
6909
6999
|
}
|
|
6910
|
-
async
|
|
6911
|
-
const accounts = await
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
7000
|
+
async findAndParseUserStates(owner) {
|
|
7001
|
+
const accounts = await (0, helpers_1.getProgramAccountsV2)(constants_1.KAMINO_FARM_PROGRAM, 10, [
|
|
7002
|
+
{ dataSize: 920 },
|
|
7003
|
+
{ memcmp: { offset: 48, bytes: owner.toBase58() } },
|
|
7004
|
+
]);
|
|
7005
|
+
return accounts.map(({ pubkey, account }) => {
|
|
7006
|
+
// farmState: [16, 48]
|
|
7007
|
+
// owner: [48, 80]
|
|
7008
|
+
// isFarmDelegated + padding: [80, 88]
|
|
7009
|
+
// rewardsTallyScaled: [88, 248]
|
|
7010
|
+
// unclaimedRewards[0..10]: [248, 328]
|
|
7011
|
+
const farmState = new web3_js_1.PublicKey(account.data.subarray(16, 48));
|
|
7012
|
+
const rewardsOffset = 248;
|
|
7013
|
+
const numRewards = 10;
|
|
7014
|
+
const rewardSize = 8;
|
|
7015
|
+
const rewardsData = account.data.subarray(rewardsOffset, rewardsOffset + numRewards * rewardSize);
|
|
7016
|
+
const unclaimedRewards = Array.from({ length: numRewards }, (_, i) => {
|
|
7017
|
+
const rewardData = rewardsData.subarray(i * rewardSize, (i + 1) * rewardSize);
|
|
7018
|
+
return new anchor_1.BN(rewardData, "le");
|
|
7019
|
+
});
|
|
6920
7020
|
return {
|
|
6921
|
-
|
|
7021
|
+
userState: pubkey,
|
|
6922
7022
|
farmState,
|
|
7023
|
+
unclaimedRewards,
|
|
6923
7024
|
};
|
|
6924
7025
|
});
|
|
6925
7026
|
}
|
|
@@ -6974,22 +7075,25 @@ class KaminoFarmClient {
|
|
|
6974
7075
|
}
|
|
6975
7076
|
async harvestTx(txOptions = {}) {
|
|
6976
7077
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
6977
|
-
const
|
|
6978
|
-
const farmStates = await this.findAndParseFarmStates(vault);
|
|
7078
|
+
const farmStates = await this.findAndParseUserStates(this.base.vaultPda);
|
|
6979
7079
|
const parsedFarms = await this.fetchAndParseFarms(farmStates.map((f) => f.farmState));
|
|
6980
7080
|
const tx = new web3_js_1.Transaction();
|
|
6981
|
-
|
|
7081
|
+
console.log("Building transaction to harvest the following rewards:");
|
|
7082
|
+
for (const { userState, farmState, unclaimedRewards } of farmStates) {
|
|
6982
7083
|
const { globalConfig, rewards } = parsedFarms.get(farmState.toBase58());
|
|
6983
7084
|
for (const { index, mint, tokenProgram, rewardsVault } of rewards) {
|
|
6984
|
-
|
|
7085
|
+
if (unclaimedRewards[index].eq(new anchor_1.BN(0))) {
|
|
7086
|
+
continue;
|
|
7087
|
+
}
|
|
7088
|
+
console.log(`userState: ${userState}, farmState: ${farmState}, unclaimedReward: ${unclaimedRewards[index]}, token: ${mint}`);
|
|
6985
7089
|
const vaultAta = this.base.getVaultAta(mint, tokenProgram);
|
|
6986
|
-
const createAtaIx = (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(glamSigner, vaultAta,
|
|
7090
|
+
const createAtaIx = (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(glamSigner, vaultAta, this.base.vaultPda, mint, tokenProgram);
|
|
6987
7091
|
const harvestIx = await this.base.program.methods
|
|
6988
7092
|
.kaminoFarmHarvestReward(new anchor_1.BN(index))
|
|
6989
7093
|
.accounts({
|
|
6990
7094
|
glamState: this.base.statePda,
|
|
6991
7095
|
glamSigner,
|
|
6992
|
-
userState
|
|
7096
|
+
userState,
|
|
6993
7097
|
farmState,
|
|
6994
7098
|
globalConfig,
|
|
6995
7099
|
rewardMint: mint,
|
|
@@ -7004,6 +7108,9 @@ class KaminoFarmClient {
|
|
|
7004
7108
|
tx.add(createAtaIx, harvestIx);
|
|
7005
7109
|
}
|
|
7006
7110
|
}
|
|
7111
|
+
if (tx.instructions.length === 0) {
|
|
7112
|
+
throw new Error("No rewards to harvest");
|
|
7113
|
+
}
|
|
7007
7114
|
const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
|
|
7008
7115
|
return vTx;
|
|
7009
7116
|
}
|
|
@@ -7504,16 +7611,48 @@ class InvestClient {
|
|
|
7504
7611
|
constructor(base) {
|
|
7505
7612
|
this.base = base;
|
|
7506
7613
|
}
|
|
7614
|
+
/**
|
|
7615
|
+
* Subscribe to a tokenized vault
|
|
7616
|
+
*
|
|
7617
|
+
* @param asset Deposit asset
|
|
7618
|
+
* @param amount
|
|
7619
|
+
* @param mintId
|
|
7620
|
+
* @param queued by default false, set to true to subscribe in queued mode
|
|
7621
|
+
* @param txOptions
|
|
7622
|
+
* @returns
|
|
7623
|
+
*/
|
|
7507
7624
|
async subscribe(asset, amount, mintId = 0, queued = false, txOptions = {}) {
|
|
7508
7625
|
const tx = await (queued
|
|
7509
7626
|
? this.queuedSubscribeTx(asset, amount, mintId, txOptions)
|
|
7510
7627
|
: this.subscribeTx(asset, amount, mintId, txOptions));
|
|
7511
7628
|
return await this.base.sendAndConfirm(tx);
|
|
7512
7629
|
}
|
|
7630
|
+
/**
|
|
7631
|
+
* Request to redeem share tokens of a tokenized vault in queued mode
|
|
7632
|
+
*
|
|
7633
|
+
* @param amount
|
|
7634
|
+
* @param mintId
|
|
7635
|
+
* @param txOptions
|
|
7636
|
+
* @returns
|
|
7637
|
+
*/
|
|
7513
7638
|
async queuedRedeem(amount, mintId = 0, txOptions = {}) {
|
|
7514
7639
|
const tx = await this.queuedRedeemTx(amount, mintId, txOptions);
|
|
7515
7640
|
return await this.base.sendAndConfirm(tx);
|
|
7516
7641
|
}
|
|
7642
|
+
/**
|
|
7643
|
+
* Redeem share tokens of a tokenized vault instantly. Preconditions:
|
|
7644
|
+
* 1. The vault must allow permissionless fulfillment
|
|
7645
|
+
* 2. The vault must have sufficient liquidity
|
|
7646
|
+
*
|
|
7647
|
+
* @param amount
|
|
7648
|
+
* @param mintId
|
|
7649
|
+
* @param txOptions
|
|
7650
|
+
* @returns
|
|
7651
|
+
*/
|
|
7652
|
+
async instantRedeem(amount, mintId = 0, txOptions = {}) {
|
|
7653
|
+
const tx = await this.instantRedeemTx(amount, mintId, txOptions);
|
|
7654
|
+
return await this.base.sendAndConfirm(tx);
|
|
7655
|
+
}
|
|
7517
7656
|
async fulfill(mintId = 0, txOptions = {}) {
|
|
7518
7657
|
const tx = await this.fulfillTx(mintId, txOptions);
|
|
7519
7658
|
return await this.base.sendAndConfirm(tx);
|
|
@@ -7563,7 +7702,6 @@ class InvestClient {
|
|
|
7563
7702
|
signerPolicy = (0, glamPDAs_1.getAccountPolicyPda)(this.base.getMintAta(signer));
|
|
7564
7703
|
console.log(`signerPolicy: ${signerPolicy} for signer ${signer} and token account ${mintTo}`);
|
|
7565
7704
|
}
|
|
7566
|
-
// @ts-ignore
|
|
7567
7705
|
const tx = await this.base.program.methods
|
|
7568
7706
|
.subscribe(0, amount)
|
|
7569
7707
|
.accounts({
|
|
@@ -7617,6 +7755,67 @@ class InvestClient {
|
|
|
7617
7755
|
.transaction();
|
|
7618
7756
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
7619
7757
|
}
|
|
7758
|
+
async instantRedeemTx(amount, mintId = 0, txOptions = {}) {
|
|
7759
|
+
if (mintId !== 0) {
|
|
7760
|
+
throw new Error("mintId must be 0");
|
|
7761
|
+
}
|
|
7762
|
+
// Instant redemption flow is realized by enqueueing a redemption, fulfilling it, and then claiming the tokens in a single transaction.
|
|
7763
|
+
const preInstructions = txOptions.preInstructions || [];
|
|
7764
|
+
const signer = txOptions.signer || this.base.getSigner();
|
|
7765
|
+
const glamMint = this.base.mintPda;
|
|
7766
|
+
const stateModel = await this.base.fetchStateModel();
|
|
7767
|
+
const baseAsset = stateModel.baseAsset;
|
|
7768
|
+
const signerAta = this.base.getAta(baseAsset, signer);
|
|
7769
|
+
const fulfillIx = await this.base.program.methods
|
|
7770
|
+
.fulfill(mintId)
|
|
7771
|
+
.accounts({
|
|
7772
|
+
glamState: this.base.statePda,
|
|
7773
|
+
glamMint,
|
|
7774
|
+
signer,
|
|
7775
|
+
asset: baseAsset,
|
|
7776
|
+
depositTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
7777
|
+
})
|
|
7778
|
+
.instruction();
|
|
7779
|
+
preInstructions.push((0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(signer, signerAta, signer, baseAsset));
|
|
7780
|
+
const claimIx = await this.base.program.methods
|
|
7781
|
+
.claim(0)
|
|
7782
|
+
.accounts({
|
|
7783
|
+
glamState: this.base.statePda,
|
|
7784
|
+
signer,
|
|
7785
|
+
tokenMint: baseAsset,
|
|
7786
|
+
claimTokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
7787
|
+
})
|
|
7788
|
+
.instruction();
|
|
7789
|
+
const remainingAccounts = [];
|
|
7790
|
+
if (await this.base.isLockupEnabled()) {
|
|
7791
|
+
const extraMetasAccount = this.base.extraMetasPda;
|
|
7792
|
+
const signerPolicy = (0, glamPDAs_1.getAccountPolicyPda)(this.base.getMintAta(signer));
|
|
7793
|
+
const escrow = this.base.escrowPda;
|
|
7794
|
+
const escrowPolicy = (0, glamPDAs_1.getAccountPolicyPda)(this.base.getMintAta(escrow));
|
|
7795
|
+
remainingAccounts.push(...[
|
|
7796
|
+
extraMetasAccount,
|
|
7797
|
+
signerPolicy,
|
|
7798
|
+
escrowPolicy,
|
|
7799
|
+
constants_1.TRANSFER_HOOK_PROGRAM,
|
|
7800
|
+
]);
|
|
7801
|
+
}
|
|
7802
|
+
const tx = await this.base.program.methods
|
|
7803
|
+
.queuedRedeem(0, amount)
|
|
7804
|
+
.accounts({
|
|
7805
|
+
glamState: this.base.statePda,
|
|
7806
|
+
glamMint,
|
|
7807
|
+
signer,
|
|
7808
|
+
})
|
|
7809
|
+
.remainingAccounts(remainingAccounts.map((pubkey) => ({
|
|
7810
|
+
pubkey,
|
|
7811
|
+
isSigner: false,
|
|
7812
|
+
isWritable: false,
|
|
7813
|
+
})))
|
|
7814
|
+
.preInstructions(preInstructions)
|
|
7815
|
+
.postInstructions([fulfillIx, claimIx])
|
|
7816
|
+
.transaction();
|
|
7817
|
+
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
7818
|
+
}
|
|
7620
7819
|
async queuedRedeemTx(amount, mintId = 0, txOptions = {}) {
|
|
7621
7820
|
if (mintId !== 0) {
|
|
7622
7821
|
throw new Error("mintId must be 0");
|
|
@@ -8521,6 +8720,7 @@ class CliConfig {
|
|
|
8521
8720
|
}
|
|
8522
8721
|
process.env.ANCHOR_PROVIDER_URL = cliConfig.json_rpc_url;
|
|
8523
8722
|
process.env.ANCHOR_WALLET = cliConfig.keypair_path;
|
|
8723
|
+
process.env.HELIUS_API_KEY = cliConfig.priority_fee?.helius_api_key;
|
|
8524
8724
|
return cliConfig;
|
|
8525
8725
|
}
|
|
8526
8726
|
catch (err) {
|
|
@@ -10083,17 +10283,28 @@ function installInvestCommands(tokenized, glamClient, cliConfig, txOptions) {
|
|
|
10083
10283
|
});
|
|
10084
10284
|
tokenized
|
|
10085
10285
|
.command("redeem <amount>")
|
|
10286
|
+
.option("-i, --instant", "Redeem share tokens instantly", false)
|
|
10287
|
+
.option("-y, --yes", "Skip confirmation prompt", false)
|
|
10086
10288
|
.description("Request to redeem share tokens")
|
|
10087
|
-
.
|
|
10088
|
-
.action(async (amount, options) => {
|
|
10289
|
+
.action(async (amount, { instant, yes }) => {
|
|
10089
10290
|
const amountBN = new anchor_1.BN(parseFloat(amount) * web3_js_1.LAMPORTS_PER_SOL);
|
|
10090
|
-
|
|
10091
|
-
(await (0, utils_1.confirmOperation)(`Confirm queued redemption of ${amount} shares?`));
|
|
10291
|
+
yes ||
|
|
10292
|
+
(await (0, utils_1.confirmOperation)(`Confirm ${instant ? "instant" : "queued"} redemption of ${amount} shares?`));
|
|
10092
10293
|
try {
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10294
|
+
let txSig;
|
|
10295
|
+
if (instant) {
|
|
10296
|
+
const preInstructions = await glamClient.price.priceVaultIxs(glam_sdk_1.PriceDenom.SOL);
|
|
10297
|
+
const lookupTables = glamClient.price.lookupTables;
|
|
10298
|
+
txSig = await glamClient.invest.instantRedeem(amountBN, 0, {
|
|
10299
|
+
...txOptions,
|
|
10300
|
+
preInstructions,
|
|
10301
|
+
lookupTables,
|
|
10302
|
+
});
|
|
10303
|
+
}
|
|
10304
|
+
else {
|
|
10305
|
+
txSig = await glamClient.invest.queuedRedeem(amountBN, 0, txOptions);
|
|
10306
|
+
}
|
|
10307
|
+
console.log(`${glamClient.signer} ${instant ? "instantly" : "queued"} redeemed:`, txSig);
|
|
10097
10308
|
}
|
|
10098
10309
|
catch (e) {
|
|
10099
10310
|
console.error((0, utils_1.parseTxError)(e));
|
|
@@ -10132,6 +10343,20 @@ function installInvestCommands(tokenized, glamClient, cliConfig, txOptions) {
|
|
|
10132
10343
|
throw e;
|
|
10133
10344
|
}
|
|
10134
10345
|
});
|
|
10346
|
+
tokenized
|
|
10347
|
+
.command("set-permissionless-fulfill")
|
|
10348
|
+
.argument("<enabled>", "Enable or disable permissionless fulfillment", (v) => v === "true" || v === "1", false)
|
|
10349
|
+
.description("Enable or disable permissionless fulfillment")
|
|
10350
|
+
.action(async (enabled) => {
|
|
10351
|
+
try {
|
|
10352
|
+
const txSig = await glamClient.mint.setPermissionlessFulfill(enabled);
|
|
10353
|
+
console.log(`Permissionless fulfillment set to ${enabled}:`, txSig);
|
|
10354
|
+
}
|
|
10355
|
+
catch (e) {
|
|
10356
|
+
console.error((0, utils_1.parseTxError)(e));
|
|
10357
|
+
process.exit(1);
|
|
10358
|
+
}
|
|
10359
|
+
});
|
|
10135
10360
|
}
|
|
10136
10361
|
|
|
10137
10362
|
|
|
@@ -10150,7 +10375,7 @@ function installAltCommands(alt, glamClient, cliConfig, txOptions = {}) {
|
|
|
10150
10375
|
.description("Create address lookup table (ALT) for the active GLAM")
|
|
10151
10376
|
.action(async () => {
|
|
10152
10377
|
try {
|
|
10153
|
-
const response = await fetch(`https://
|
|
10378
|
+
const response = await fetch(`https://api.glam.systems/v0/lut/vault/create?state=${glamClient.statePda}&payer=${glamClient.getSigner()}`);
|
|
10154
10379
|
const data = await response.json();
|
|
10155
10380
|
const table = data.tables[0];
|
|
10156
10381
|
const b64Txs = data.tx;
|
|
@@ -10642,7 +10867,7 @@ program
|
|
|
10642
10867
|
.hook("preSubcommand", async (thisCommand, actionCommand) => {
|
|
10643
10868
|
await (0, idl_1.idlCheck)(glamClient);
|
|
10644
10869
|
})
|
|
10645
|
-
.version("0.1.
|
|
10870
|
+
.version("0.1.36");
|
|
10646
10871
|
program
|
|
10647
10872
|
.command("env")
|
|
10648
10873
|
.description("Display current environment setup")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glamsystems/glam-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.36",
|
|
4
4
|
"description": "CLI for interacting with the GLAM Protocol",
|
|
5
5
|
"main": "./main.js",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"node": ">=20.18.0"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@glamsystems/glam-sdk": "0.1.
|
|
24
|
+
"@glamsystems/glam-sdk": "0.1.36",
|
|
25
25
|
"commander": "^11.1.0",
|
|
26
26
|
"inquirer": "^8.2.6",
|
|
27
27
|
"@switchboard-xyz/common": "^3.0.0"
|