@glamsystems/glam-sdk 0.2.0-alpha.3 → 1.0.0-alpha.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/index.cjs.js CHANGED
@@ -22352,28 +22352,6 @@ const JUPSOL_STAKE_POOL = new web3_js.PublicKey("8VpRhuxa7sUUepdY3kQiTmX9rS5vx4W
22352
22352
  /**
22353
22353
  * Referrers
22354
22354
  */ const GLAM_REFERRER = new web3_js.PublicKey("GLAMrG37ZqioqvzBNQGCfCUueDz3tsr7MwMFyRk9PS89");
22355
- /**
22356
- * Integration program mapping
22357
- */ const INTEGRATION_MAPPING = {
22358
- GM1NtvvnSXUptTrMCqbogAdZJydZSNv98DoU5AZVLmGh: {
22359
- "0000000000000001": "GLAM Mint Protocol"
22360
- },
22361
- G1NTcMDYgNLpDwgnrpSZvoSKQuR9NXG7S3DmtNQCDmrK: {
22362
- "0000000000000001": "CCTP"
22363
- },
22364
- G1NTsQ36mjPe89HtPYqxKsjY5HmYsDR6CbD2gd2U2pta: {
22365
- "0000000000000001": "Token"
22366
- },
22367
- G1NTdrBmBpW43msRQmsf7qXSw3MFBNaqJcAkGiRmRq2F: {
22368
- "0000000000000001": "Drift Protocol",
22369
- "0000000000000010": "Drift Vaults"
22370
- },
22371
- G1NTkDEUR3pkEqGCKZtmtmVzCUEdYa86pezHkwYbLyde: {
22372
- "0000000000000001": "Kamino Lending",
22373
- "0000000000000010": "Kamino Vaults",
22374
- "0000000000000100": "Kamino Farms"
22375
- }
22376
- };
22377
22355
  /**
22378
22356
  * CCTP domain to chain name mapping
22379
22357
  */ const CCTP_DOMAIN_MAPPING = {
@@ -22405,66 +22383,6 @@ const JUPSOL_STAKE_POOL = new web3_js.PublicKey("8VpRhuxa7sUUepdY3kQiTmX9rS5vx4W
22405
22383
  3: "Exponent Market"
22406
22384
  };
22407
22385
  // Permission mappings for each protocol - maps bit positions to permission names
22408
- const PERMISSION_MAPPINGS = {
22409
- // Kamino integration program
22410
- G1NTkDEUR3pkEqGCKZtmtmVzCUEdYa86pezHkwYbLyde: {
22411
- // Kamino Lending (protocol bitmask: 0000000000000001)
22412
- "0000000000000001": {
22413
- 0: "Init",
22414
- 1: "Deposit",
22415
- 2: "Withdraw",
22416
- 3: "Borrow",
22417
- 4: "Repay"
22418
- },
22419
- // Kamino Vaults (protocol bitmask: 0000000000000010)
22420
- "0000000000000010": {
22421
- 0: "Deposit",
22422
- 1: "Withdraw"
22423
- },
22424
- // Kamino Farms (protocol bitmask: 0000000000000100)
22425
- "0000000000000100": {
22426
- 0: "Stake",
22427
- 1: "Unstake",
22428
- 2: "HarvestReward"
22429
- }
22430
- },
22431
- // Drift integration program
22432
- G1NTdrBmBpW43msRQmsf7qXSw3MFBNaqJcAkGiRmRq2F: {
22433
- // Drift Protocol (protocol bitmask: 0000000000000001)
22434
- "0000000000000001": {
22435
- 0: "InitUser",
22436
- 1: "UpdateUser",
22437
- 2: "DeleteUser",
22438
- 3: "Deposit",
22439
- 4: "Withdraw",
22440
- 5: "Borrow",
22441
- 6: "CreateModifyOrders",
22442
- 7: "CancelOrders",
22443
- 8: "PerpMarkets",
22444
- 9: "SpotMarkets"
22445
- },
22446
- // Drift Vaults (protocol bitmask: 0000000000000010)
22447
- "0000000000000010": {
22448
- 0: "Deposit",
22449
- 1: "Withdraw"
22450
- }
22451
- },
22452
- // Token integration program
22453
- G1NTsQ36mjPe89HtPYqxKsjY5HmYsDR6CbD2gd2U2pta: {
22454
- // Token (protocol bitmask: 0000000000000001)
22455
- "0000000000000001": {
22456
- 0: "Transfer"
22457
- }
22458
- },
22459
- // CCTP integration program
22460
- G1NTcMDYgNLpDwgnrpSZvoSKQuR9NXG7S3DmtNQCDmrK: {
22461
- // CCTP (protocol bitmask: 0000000000000001)
22462
- "0000000000000001": {
22463
- 0: "Transfer"
22464
- }
22465
- }
22466
- };
22467
- // Permission mappings for each protocol - maps bit positions to permission names
22468
22386
  const PROTOCOLS_AND_PERMISSIONS = {
22469
22387
  // Self integration
22470
22388
  GLAMpaME8wdTEzxtiYEAa5yD8fZbxZiz2hNtV58RZiEz: {
@@ -22494,16 +22412,22 @@ const PROTOCOLS_AND_PERMISSIONS = {
22494
22412
  // GLAM mint
22495
22413
  GM1NtvvnSXUptTrMCqbogAdZJydZSNv98DoU5AZVLmGh: {
22496
22414
  "0000000000000001": {
22497
- name: "GLAM Mint",
22415
+ name: "Glam Mint",
22498
22416
  permissions: {
22499
- [1 << 0]: "Mint"
22417
+ [1 << 0]: "MintTokens",
22418
+ [1 << 1]: "BurnTokens",
22419
+ [1 << 2]: "ForceTransfer",
22420
+ [1 << 3]: "SetTokenAccountState",
22421
+ [1 << 4]: "ClaimFees",
22422
+ [1 << 5]: "Fulfill",
22423
+ [1 << 6]: "EmergencyUpdate"
22500
22424
  }
22501
22425
  }
22502
22426
  },
22503
22427
  // Kamino integration program
22504
22428
  G1NTkDEUR3pkEqGCKZtmtmVzCUEdYa86pezHkwYbLyde: {
22505
22429
  "0000000000000001": {
22506
- name: "Kamino Lending",
22430
+ name: "Kamino Lend",
22507
22431
  permissions: {
22508
22432
  [1 << 0]: "Init",
22509
22433
  [1 << 1]: "Deposit",
@@ -22556,7 +22480,7 @@ const PROTOCOLS_AND_PERMISSIONS = {
22556
22480
  // Token integration program
22557
22481
  G1NTsQ36mjPe89HtPYqxKsjY5HmYsDR6CbD2gd2U2pta: {
22558
22482
  "0000000000000001": {
22559
- name: "Token",
22483
+ name: "Spl Token",
22560
22484
  permissions: {
22561
22485
  [1 << 0]: "Transfer"
22562
22486
  }
@@ -22572,6 +22496,33 @@ const PROTOCOLS_AND_PERMISSIONS = {
22572
22496
  }
22573
22497
  }
22574
22498
  };
22499
+ /**
22500
+ * (Program ID, Bitflag) -> Protocol Name
22501
+ */ const PROTOCOL_NAME_BY_PROGRAM_AND_BITFLAG = (()=>{
22502
+ const mapping = {};
22503
+ Object.entries(PROTOCOLS_AND_PERMISSIONS).forEach(([programId, protocols])=>{
22504
+ mapping[programId] = {};
22505
+ Object.entries(protocols).forEach(([bitflag, protocol])=>{
22506
+ mapping[programId][bitflag] = protocol.name;
22507
+ });
22508
+ });
22509
+ return mapping;
22510
+ })();
22511
+ /**
22512
+ * Protocol Name -> (Program ID, Bitflag)
22513
+ */ const PROGRAM_AND_BITFLAG_BY_PROTOCOL_NAME = (()=>{
22514
+ const mapping = {};
22515
+ Object.entries(PROTOCOLS_AND_PERMISSIONS).forEach(([programId, protocols])=>{
22516
+ Object.entries(protocols).forEach(([bitflag, protocol])=>{
22517
+ const name = protocol.name.replace(" ", "");
22518
+ mapping[name] = [
22519
+ programId,
22520
+ bitflag
22521
+ ];
22522
+ });
22523
+ });
22524
+ return mapping;
22525
+ })();
22575
22526
 
22576
22527
  // Example response from Helius:
22577
22528
  // {
@@ -22668,7 +22619,7 @@ async function getProgramAccountsWithRetry(connection, programId, filters) {
22668
22619
  await new Promise((resolve)=>setTimeout(resolve, delayMs * attempt));
22669
22620
  }
22670
22621
  }
22671
- throw new Error(`Failed after ${maxRetries} attempts. Last error: ${lastError.message}`);
22622
+ throw new Error(`Failed after ${maxRetries} attempts. Last error: ${lastError?.message || "Unknown error"}`);
22672
22623
  }
22673
22624
  /**
22674
22625
  * Fetches all the token accounts owned by the specified pubkey.
@@ -23076,10 +23027,32 @@ MintPolicy._layout = borsh.struct([
23076
23027
  borsh.option(borsh.vec(borsh.publicKey()), "allowlist"),
23077
23028
  borsh.option(borsh.vec(borsh.publicKey()), "blocklist")
23078
23029
  ]);
23030
+ class JupiterSwapPolicy {
23031
+ static decode(buffer) {
23032
+ const policy = JupiterSwapPolicy._layout.decode(buffer);
23033
+ return new JupiterSwapPolicy(policy.maxSlippageBps, policy.swapAllowlist);
23034
+ }
23035
+ encode() {
23036
+ const swapAllowlistSize = this.swapAllowlist ? 1 + 4 + this.swapAllowlist.length * 32 : 1;
23037
+ const totalSize = 4 + swapAllowlistSize;
23038
+ const buffer = Buffer.alloc(totalSize);
23039
+ JupiterSwapPolicy._layout.encode(this, buffer);
23040
+ return buffer;
23041
+ }
23042
+ constructor(maxSlippageBps, swapAllowlist){
23043
+ this.maxSlippageBps = maxSlippageBps;
23044
+ this.swapAllowlist = swapAllowlist;
23045
+ }
23046
+ }
23047
+ JupiterSwapPolicy._layout = borsh.struct([
23048
+ borsh.u32("maxSlippageBps"),
23049
+ borsh.option(borsh.vec(borsh.publicKey()), "swapAllowlist")
23050
+ ]);
23051
+ // System Program and Token Program use the same TransferPolicy struct
23079
23052
  class TransferPolicy {
23080
23053
  static decode(buffer) {
23081
- const data = TransferPolicy._layout.decode(buffer);
23082
- return data;
23054
+ const { allowlist } = TransferPolicy._layout.decode(buffer);
23055
+ return new TransferPolicy(allowlist);
23083
23056
  }
23084
23057
  encode() {
23085
23058
  const header = Buffer.alloc(4);
@@ -23153,6 +23126,47 @@ DriftProtocolPolicy._layout = borsh.struct([
23153
23126
  borsh.vec(borsh.u16(), "perpMarketsAllowlist"),
23154
23127
  borsh.vec(borsh.publicKey(), "borrowAllowlist")
23155
23128
  ]);
23129
+ class KaminoLendingPolicy {
23130
+ static decode(buffer) {
23131
+ const { marketsAllowlist, borrowAllowlist } = KaminoLendingPolicy._layout.decode(buffer);
23132
+ return new KaminoLendingPolicy(marketsAllowlist, borrowAllowlist);
23133
+ }
23134
+ encode() {
23135
+ const marketsAllowlistSize = 4 + this.marketsAllowlist.length * 32;
23136
+ const borrowAllowlistSize = 4 + this.borrowAllowlist.length * 32;
23137
+ const totalSize = marketsAllowlistSize + borrowAllowlistSize;
23138
+ const buffer = Buffer.alloc(totalSize);
23139
+ KaminoLendingPolicy._layout.encode(this, buffer);
23140
+ return buffer;
23141
+ }
23142
+ constructor(marketsAllowlist, borrowAllowlist){
23143
+ this.marketsAllowlist = marketsAllowlist;
23144
+ this.borrowAllowlist = borrowAllowlist;
23145
+ }
23146
+ }
23147
+ KaminoLendingPolicy._layout = borsh.struct([
23148
+ borsh.vec(borsh.publicKey(), "marketsAllowlist"),
23149
+ borsh.vec(borsh.publicKey(), "borrowAllowlist")
23150
+ ]);
23151
+ class KaminoVaultsPolicy {
23152
+ static decode(buffer) {
23153
+ const { vaultsAllowlist } = KaminoVaultsPolicy._layout.decode(buffer);
23154
+ return new KaminoVaultsPolicy(vaultsAllowlist);
23155
+ }
23156
+ encode() {
23157
+ const vaultsAllowlistSize = 4 + this.vaultsAllowlist.length * 32;
23158
+ const totalSize = vaultsAllowlistSize;
23159
+ const buffer = Buffer.alloc(totalSize);
23160
+ KaminoVaultsPolicy._layout.encode(this, buffer);
23161
+ return buffer;
23162
+ }
23163
+ constructor(vaultsAllowlist){
23164
+ this.vaultsAllowlist = vaultsAllowlist;
23165
+ }
23166
+ }
23167
+ KaminoVaultsPolicy._layout = borsh.struct([
23168
+ borsh.vec(borsh.publicKey(), "vaultsAllowlist")
23169
+ ]);
23156
23170
  class CctpPolicy {
23157
23171
  static decode(buffer) {
23158
23172
  const data = CctpPolicy._layout.decode(buffer);
@@ -23185,21 +23199,11 @@ CctpPolicy._layout = borsh.struct([
23185
23199
  ]), "allowedDestinations")
23186
23200
  ]);
23187
23201
 
23188
- function getStatePda(stateModel, programId, owner) {
23189
- if (!stateModel?.created?.key && !stateModel?.name) {
23190
- throw new Error("State model must have created key or name");
23191
- }
23192
- const createdKey = stateModel?.created?.key || [
23193
- ...Buffer.from(anchor__namespace.utils.sha256.hash(charsToName(stateModel.name))).subarray(0, 8)
23194
- ];
23195
- const stateOwner = owner || stateModel?.owner;
23196
- if (!stateOwner) {
23197
- throw new Error("Owner must be specified explicitly or set in state model");
23198
- }
23202
+ function getStatePda(initKey, owner, programId) {
23199
23203
  const [pda, _bump] = web3_js.PublicKey.findProgramAddressSync([
23200
23204
  Buffer.from(SEED_STATE),
23201
- stateOwner.toBuffer(),
23202
- Uint8Array.from(createdKey)
23205
+ owner.toBuffer(),
23206
+ Uint8Array.from(initKey)
23203
23207
  ], programId);
23204
23208
  return pda;
23205
23209
  }
@@ -23254,8 +23258,6 @@ function getAccountPolicyPda(tokenAccount) {
23254
23258
  ], TRANSFER_HOOK_PROGRAM)[0];
23255
23259
  }
23256
23260
 
23257
- const GlamIntegrations = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Integration")?.type?.variants?.map((v)=>v.name) ?? [];
23258
- const GlamPermissions = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Permission")?.type?.variants?.map((v)=>v.name).filter((v)=>!v.startsWith("__")) ?? [];
23259
23261
  const GLAM_PROTOCOL_PROGRAM_ID = new web3_js.PublicKey(GlamProtocolIdlJson.address);
23260
23262
  class StateIdlModel {
23261
23263
  constructor(data){
@@ -23274,14 +23276,19 @@ class StateIdlModel {
23274
23276
  this.integrationAcls = data.integrationAcls ?? null;
23275
23277
  }
23276
23278
  }
23277
- class StateModel extends StateIdlModel {
23279
+ /**
23280
+ * Enriched state model built from multiple onchain accounts
23281
+ */ class StateModel extends StateIdlModel {
23278
23282
  get idStr() {
23279
23283
  return this.id?.toBase58() || "";
23280
23284
  }
23281
23285
  get nameStr() {
23282
- return charsToName(this.name);
23286
+ return this.name ? charsToName(this.name) : "";
23283
23287
  }
23284
23288
  get vault() {
23289
+ if (!this.id) {
23290
+ throw new Error("State ID not initialized");
23291
+ }
23285
23292
  return getVaultPda(this.id, this.glamProgramId);
23286
23293
  }
23287
23294
  get productType() {
@@ -23294,6 +23301,9 @@ class StateModel extends StateIdlModel {
23294
23301
  return new Date(createdAt * 1000).toISOString().split("T")[0] || "Unknown";
23295
23302
  }
23296
23303
  get sparkleKey() {
23304
+ if (!this.mint || !this.id) {
23305
+ throw new Error("Mint or state pubkey not set");
23306
+ }
23297
23307
  return (this.mint.equals(web3_js.PublicKey.default) ? this.id : this.mint).toBase58();
23298
23308
  }
23299
23309
  get baseAssetTokenProgramId() {
@@ -23368,6 +23378,7 @@ class StateModel extends StateIdlModel {
23368
23378
  const name = Object.keys(param.name)[0];
23369
23379
  // @ts-ignore
23370
23380
  const value = Object.values(param.value)[0].val;
23381
+ // @ts-ignore
23371
23382
  mintModel[name] = value;
23372
23383
  });
23373
23384
  // Parse token extensions
@@ -23448,7 +23459,7 @@ class MintIdlModel {
23448
23459
  }
23449
23460
  class MintModel extends MintIdlModel {
23450
23461
  get nameStr() {
23451
- return charsToName(this.name);
23462
+ return this.name ? charsToName(this.name) : "";
23452
23463
  }
23453
23464
  constructor(data){
23454
23465
  super(data);
@@ -23499,12 +23510,6 @@ class ProtocolPermissions {
23499
23510
  this.permissionsBitmask = obj.permissionsBitmask;
23500
23511
  }
23501
23512
  }
23502
- class JupiterSwapPolicy {
23503
- constructor(obj){
23504
- this.maxSlippageBps = obj.maxSlippageBps;
23505
- this.swapAllowlist = obj.swapAllowlist ?? null;
23506
- }
23507
- }
23508
23513
  class ProtocolPolicy {
23509
23514
  constructor(obj){
23510
23515
  this.protocolBitflag = obj.protocolBitflag;
@@ -24565,7 +24570,7 @@ class BaseClient {
24565
24570
  /**
24566
24571
  * Fetches mint accounts and token program IDs for the given mint pubkeys
24567
24572
  */ async fetchMintsAndTokenPrograms(mintPubkeys) {
24568
- const accountsInfo = (await this.provider.connection.getMultipleAccountsInfo(mintPubkeys, "confirmed")).filter(Boolean);
24573
+ const accountsInfo = (await this.provider.connection.getMultipleAccountsInfo(mintPubkeys, "confirmed")).filter((info)=>info !== null);
24569
24574
  if (accountsInfo.length !== mintPubkeys.length) {
24570
24575
  throw new Error(`Failed to fetch mint accounts for ${mintPubkeys.length} mints`);
24571
24576
  }
@@ -24575,6 +24580,9 @@ class BaseClient {
24575
24580
  * Fetches mint account and token program ID for the given mint pubkey
24576
24581
  */ async fetchMintAndTokenProgram(mintPubkey) {
24577
24582
  const info = await this.provider.connection.getAccountInfo(mintPubkey, "confirmed");
24583
+ if (!info) {
24584
+ throw new Error(`Failed to fetch mint account for ${mintPubkey.toBase58()}`);
24585
+ }
24578
24586
  return this.parseMintAccountInfo(info, mintPubkey);
24579
24587
  }
24580
24588
  /**
@@ -24712,6 +24720,15 @@ class BaseClient {
24712
24720
  return StateModel.fromOnchainAccounts(publicKey, stateAccount, mintsCache.get(stateAccount.mint.toBase58()), this.protocolProgram.programId);
24713
24721
  });
24714
24722
  }
24723
+ async fetchProtocolPolicy(integProgramId, protocolBitflag, policyClass) {
24724
+ const stateAccount = await this.fetchStateAccount();
24725
+ const integrationPolicy = stateAccount.integrationAcls?.find((acl)=>acl.integrationProgram.equals(integProgramId));
24726
+ const policyData = integrationPolicy?.protocolPolicies?.find((policy)=>policy.protocolBitflag === protocolBitflag)?.data;
24727
+ if (policyData) {
24728
+ return policyClass.decode(policyData);
24729
+ }
24730
+ return null;
24731
+ }
24715
24732
  constructor(config){
24716
24733
  if (config?.provider) {
24717
24734
  this.provider = config?.provider;
@@ -26504,12 +26521,13 @@ class DriftVaultsClient {
26504
26521
  async parseDriftVaults(driftVaults) {
26505
26522
  const connection = this.base.provider.connection;
26506
26523
  const accountsInfo = await connection.getMultipleAccountsInfo(driftVaults);
26507
- accountsInfo.forEach((accountInfo, i)=>{
26524
+ const validAccountsInfo = accountsInfo.map((accountInfo, i)=>{
26508
26525
  if (!accountInfo) {
26509
26526
  throw new Error(`Drift vault account not found: ${driftVaults[i]}`);
26510
26527
  }
26528
+ return accountInfo;
26511
26529
  });
26512
- return accountsInfo.map((accountInfo, i)=>{
26530
+ return validAccountsInfo.map((accountInfo)=>{
26513
26531
  return DriftVault.decode(accountInfo.data);
26514
26532
  });
26515
26533
  }
@@ -26740,14 +26758,6 @@ async function getSwapInstructions(quoteResponse, from) {
26740
26758
  return await res.json();
26741
26759
  }
26742
26760
  let TxBuilder$3 = class TxBuilder {
26743
- async setJupiterSwapPolicy(policy, txOptions = {}) {
26744
- const glamSigner = txOptions.signer || this.base.getSigner();
26745
- const tx = await this.base.protocolProgram.methods.setJupiterSwapPolicy(policy).accounts({
26746
- glamState: this.base.statePda,
26747
- glamSigner
26748
- }).transaction();
26749
- return this.base.intoVersionedTransaction(tx, txOptions);
26750
- }
26751
26761
  async swap(options, txOptions = {}) {
26752
26762
  const glamSigner = txOptions.signer || this.base.getSigner();
26753
26763
  const glamVault = this.base.vaultPda;
@@ -26845,10 +26855,6 @@ class JupiterSwapClient {
26845
26855
  const tx = await this.txBuilder.swap(options, txOptions);
26846
26856
  return await this.base.sendAndConfirm(tx);
26847
26857
  }
26848
- async setJupiterSwapPolicy(policy, txOptions = {}) {
26849
- const tx = await this.txBuilder.setJupiterSwapPolicy(policy, txOptions);
26850
- return await this.base.sendAndConfirm(tx);
26851
- }
26852
26858
  constructor(base){
26853
26859
  this.base = base;
26854
26860
  this.txBuilder = new TxBuilder$3(base);
@@ -27198,7 +27204,7 @@ class VaultClient {
27198
27204
  }
27199
27205
  /**
27200
27206
  * Returns an instruction that closes the specified vault token account
27201
- */ async closeTokenAccountIx(tokenAccount, tokenProgram = splToken.TOKEN_PROGRAM_ID, txOptions) {
27207
+ */ async closeTokenAccountIx(tokenAccount, tokenProgram = splToken.TOKEN_PROGRAM_ID, txOptions = {}) {
27202
27208
  return await this.base.extSplProgram.methods.tokenCloseAccount().accounts({
27203
27209
  glamState: this.base.statePda,
27204
27210
  glamSigner: txOptions.signer || this.base.signer,
@@ -27269,6 +27275,24 @@ class VaultClient {
27269
27275
  const tx = new web3_js.Transaction().add(splToken.createAssociatedTokenAccountIdempotentInstruction(signer, vaultAta, this.base.vaultPda, asset, tokenProgram), splToken.createTransferCheckedInstruction(signerAta, asset, vaultAta, signer, new anchor.BN(amount).toNumber(), mint.decimals, [], tokenProgram));
27270
27276
  return await this.base.intoVersionedTransaction(tx, txOptions);
27271
27277
  }
27278
+ async tokenTransferIxs(mint, amount, to, txOptions = {}) {
27279
+ const glamSigner = txOptions.signer || this.base.signer;
27280
+ const { mint: mintObj, tokenProgram } = await this.base.fetchMintAndTokenProgram(mint);
27281
+ const toAta = this.base.getAta(mint, to, tokenProgram);
27282
+ const preIx = splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, toAta, to, mint, tokenProgram);
27283
+ const ix = await this.base.extSplProgram.methods.tokenTransferChecked(new anchor.BN(amount), mintObj.decimals).accounts({
27284
+ glamState: this.base.statePda,
27285
+ glamSigner,
27286
+ from: this.base.getVaultAta(mint, tokenProgram),
27287
+ to: toAta,
27288
+ mint,
27289
+ cpiProgram: tokenProgram
27290
+ }).instruction();
27291
+ return [
27292
+ preIx,
27293
+ ix
27294
+ ];
27295
+ }
27272
27296
  async tokenTransferTx(mint, amount, to, txOptions) {
27273
27297
  const glamSigner = txOptions.signer || this.base.signer;
27274
27298
  const { mint: mintObj, tokenProgram } = await this.base.fetchMintAndTokenProgram(mint);
@@ -27754,6 +27778,9 @@ let TxBuilder$2 = class TxBuilder {
27754
27778
  const glamSigner = txOptions.signer || this.base.signer;
27755
27779
  const stateModel = this.enrichStateModel(partialStateModel);
27756
27780
  const { id: statePda } = stateModel;
27781
+ if (!statePda) {
27782
+ throw new Error("State PDA not set");
27783
+ }
27757
27784
  const tx = await this.base.protocolProgram.methods.initializeState(new StateIdlModel(stateModel)).accountsPartial({
27758
27785
  glamState: statePda,
27759
27786
  glamSigner,
@@ -27798,7 +27825,7 @@ let TxBuilder$2 = class TxBuilder {
27798
27825
  * Create an enriched state model from a partial IDL state model
27799
27826
  */ enrichStateModel(stateModel) {
27800
27827
  if (!stateModel?.name) {
27801
- throw new Error("Name must be specified in partial state model");
27828
+ throw new Error("Name must be specified");
27802
27829
  }
27803
27830
  // stateInitKey = hash state name and get first 8 bytes
27804
27831
  // useful for computing state account PDA in the future
@@ -27809,7 +27836,7 @@ let TxBuilder$2 = class TxBuilder {
27809
27836
  key: stateInitKey
27810
27837
  });
27811
27838
  stateModel.owner = stateModel.owner || this.base.signer;
27812
- const statePda = getStatePda(stateModel, this.base.protocolProgram.programId);
27839
+ const statePda = getStatePda(stateInitKey, stateModel.owner, this.base.protocolProgram.programId);
27813
27840
  stateModel.uri = stateModel.uri || `https://gui.glam.systems/products/${statePda}`;
27814
27841
  return new StateModel({
27815
27842
  ...stateModel,
@@ -29519,7 +29546,7 @@ class PriceClient {
29519
29546
  possibleShareAtaAccountsInfo.forEach((info, i)=>{
29520
29547
  // share ata must exist and it must be tracked by glam state
29521
29548
  // otherwise skip it for pricing
29522
- if (info !== null && this.cachedStateModel.externalPositions?.find((a)=>a.equals(possibleShareAtas[i]))) {
29549
+ if (info !== null && this.cachedStateModel?.externalPositions?.find((a)=>a.equals(possibleShareAtas[i]))) {
29523
29550
  shareAtas.push(possibleShareAtas[i]);
29524
29551
  shareMints.push(allKvaultMints[i]);
29525
29552
  kvaultStates.push(allKvaultStates[i]);
@@ -29753,22 +29780,26 @@ class PriceClient {
29753
29780
  if (driftIntegrationAcl) {
29754
29781
  // drift protocol
29755
29782
  if (driftIntegrationAcl.protocolsBitmask & 0b01) {
29756
- pricingIxs.push(await this.priceDriftUsersIx());
29783
+ const ix = await this.priceDriftUsersIx();
29784
+ if (ix) pricingIxs.push(ix);
29757
29785
  }
29758
29786
  // drift vaults
29759
29787
  if (driftIntegrationAcl.protocolsBitmask & 0b10) {
29760
- pricingIxs.push(await this.priceDriftVaultDepositorsIx());
29788
+ const ix = await this.priceDriftVaultDepositorsIx();
29789
+ if (ix) pricingIxs.push(ix);
29761
29790
  }
29762
29791
  }
29763
29792
  const kaminoIntegrationAcl = integrationAcls.find((acl)=>acl.integrationProgram.equals(this.base.extKaminoProgram.programId));
29764
29793
  if (kaminoIntegrationAcl) {
29765
29794
  // kamino lending
29766
29795
  if (kaminoIntegrationAcl.protocolsBitmask & 0b01) {
29767
- pricingIxs.push(await this.priceKaminoObligationsIx());
29796
+ const ix = await this.priceKaminoObligationsIx();
29797
+ if (ix) pricingIxs.push(ix);
29768
29798
  }
29769
29799
  // kamino vaults
29770
29800
  if (kaminoIntegrationAcl.protocolsBitmask & 0b10) {
29771
- pricingIxs.push(...await this.priceKaminoVaultSharesIx());
29801
+ const ixs = await this.priceKaminoVaultSharesIx();
29802
+ if (ixs) pricingIxs.push(...ixs);
29772
29803
  }
29773
29804
  }
29774
29805
  return pricingIxs.filter(Boolean);
@@ -29986,17 +30017,191 @@ class FeesClient {
29986
30017
  }
29987
30018
  }
29988
30019
 
30020
+ let MintTxBuilder = class MintTxBuilder {
30021
+ /**
30022
+ * Creates a glam mint token account
30023
+ *
30024
+ * @param owner Owner of the token account
30025
+ * @param setFrozen If true, the token account will be frozen immediately
30026
+ * @param txOptions
30027
+ */ async createTokenAccount(owner, setFrozen = true, txOptions = {}) {
30028
+ const glamSigner = txOptions.signer || this.base.getSigner();
30029
+ const glamMint = this.base.mintPda;
30030
+ const ata = this.base.getMintAta(owner);
30031
+ const ixCreateAta = splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, ata, owner, glamMint, splToken.TOKEN_2022_PROGRAM_ID);
30032
+ return await this.setTokenAccountsStates([
30033
+ ata
30034
+ ], setFrozen, {
30035
+ preInstructions: [
30036
+ ixCreateAta
30037
+ ],
30038
+ ...txOptions
30039
+ });
30040
+ }
30041
+ /**
30042
+ * Freezes or unfreezes token accounts
30043
+ *
30044
+ * @param tokenAccounts List of token accounts to freeze or unfreeze
30045
+ * @param frozen If true, the token accounts will be frozen; otherwise, they will be unfrozen
30046
+ * @param txOptions
30047
+ */ async setTokenAccountsStates(tokenAccounts, frozen, txOptions = {}) {
30048
+ const glamSigner = txOptions.signer || this.base.getSigner();
30049
+ const tx = await this.base.mintProgram.methods.setTokenAccountsStates(frozen).accounts({
30050
+ glamState: this.base.statePda,
30051
+ glamSigner,
30052
+ glamMint: this.base.mintPda
30053
+ }).remainingAccounts(tokenAccounts.map((account)=>({
30054
+ pubkey: account,
30055
+ isSigner: false,
30056
+ isWritable: true
30057
+ }))).preInstructions(txOptions.preInstructions || []).transaction();
30058
+ return await this.base.intoVersionedTransaction(tx, txOptions);
30059
+ }
30060
+ /**
30061
+ * Mints tokens to recipient. Token account will be created if it does not exist.
30062
+ *
30063
+ * @param recipient Recipient public key
30064
+ * @param amount Amount of tokens to mint
30065
+ * @param forceThaw If true, automatically unfreeze the token account before minting
30066
+ * @param txOptions
30067
+ */ async mint(recipient, amount, forceThaw = false, txOptions = {}) {
30068
+ const glamSigner = txOptions.signer || this.base.signer;
30069
+ const mintTo = this.base.getMintAta(recipient);
30070
+ const preInstructions = [
30071
+ splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, mintTo, recipient, this.base.mintPda, splToken.TOKEN_2022_PROGRAM_ID)
30072
+ ];
30073
+ if (forceThaw) {
30074
+ preInstructions.push(await this.base.mintProgram.methods.setTokenAccountsStates(false).accounts({
30075
+ glamState: this.base.statePda,
30076
+ glamSigner,
30077
+ glamMint: this.base.mintPda
30078
+ }).remainingAccounts([
30079
+ {
30080
+ pubkey: mintTo,
30081
+ isSigner: false,
30082
+ isWritable: true
30083
+ }
30084
+ ]).instruction());
30085
+ }
30086
+ let policyAccount = await this.base.isLockupEnabled() ? getAccountPolicyPda(mintTo) : null;
30087
+ const tx = await this.base.mintProgram.methods.mintTokens(amount).accounts({
30088
+ glamState: this.base.statePda,
30089
+ glamSigner,
30090
+ glamMint: this.base.mintPda,
30091
+ recipient,
30092
+ policyAccount
30093
+ }).preInstructions(preInstructions).transaction();
30094
+ return await this.base.intoVersionedTransaction(tx, txOptions);
30095
+ }
30096
+ /**
30097
+ * Burns tokens from a token account
30098
+ *
30099
+ * @param from Owner of the token account
30100
+ * @param amount Amount of tokens to burn
30101
+ * @param forceThaw If true, automatically unfree the token account before burning
30102
+ * @param txOptions
30103
+ */ async burn(from, amount, forceThaw = false, txOptions = {}) {
30104
+ const glamSigner = txOptions.signer || this.base.getSigner();
30105
+ const ata = this.base.getMintAta(from);
30106
+ const preInstructions = [];
30107
+ if (forceThaw) {
30108
+ preInstructions.push(await this.base.mintProgram.methods.setTokenAccountsStates(false).accounts({
30109
+ glamState: this.base.statePda,
30110
+ glamSigner,
30111
+ glamMint: this.base.mintPda
30112
+ }).remainingAccounts([
30113
+ {
30114
+ pubkey: ata,
30115
+ isSigner: false,
30116
+ isWritable: true
30117
+ }
30118
+ ]).instruction());
30119
+ }
30120
+ const tx = await this.base.mintProgram.methods.burnTokens(amount).accounts({
30121
+ glamState: this.base.statePda,
30122
+ glamSigner,
30123
+ glamMint: this.base.mintPda,
30124
+ from
30125
+ }).preInstructions(preInstructions).transaction();
30126
+ return await this.base.intoVersionedTransaction(tx, txOptions);
30127
+ }
30128
+ /**
30129
+ * Transfers tokens from one token account to another
30130
+ *
30131
+ * @param from Owner of the sender token account
30132
+ * @param to Owner of the recipient token account
30133
+ * @param amount Amount of tokens to transfer
30134
+ * @param forceThaw If true, automatically unfree the token accounts before transfer
30135
+ * @param txOptions
30136
+ */ async forceTransfer(from, to, amount, forceThaw = false, txOptions = {}) {
30137
+ const glamSigner = txOptions.signer || this.base.getSigner();
30138
+ const fromAta = this.base.getMintAta(from);
30139
+ const toAta = this.base.getMintAta(to);
30140
+ const preInstructions = [];
30141
+ preInstructions.push(splToken.createAssociatedTokenAccountIdempotentInstruction(this.base.getSigner(), toAta, to, this.base.mintPda, splToken.TOKEN_2022_PROGRAM_ID));
30142
+ if (forceThaw) {
30143
+ preInstructions.push(await this.base.mintProgram.methods.setTokenAccountsStates(false).accounts({
30144
+ glamState: this.base.statePda,
30145
+ glamSigner,
30146
+ glamMint: this.base.mintPda
30147
+ }).remainingAccounts([
30148
+ {
30149
+ pubkey: fromAta,
30150
+ isSigner: false,
30151
+ isWritable: true
30152
+ },
30153
+ {
30154
+ pubkey: toAta,
30155
+ isSigner: false,
30156
+ isWritable: true
30157
+ }
30158
+ ]).instruction());
30159
+ }
30160
+ const remainingAccounts = [];
30161
+ let toPolicyAccount = null;
30162
+ if (await this.base.isLockupEnabled()) {
30163
+ const extraMetasAccount = this.base.extraMetasPda;
30164
+ const fromPolicy = getAccountPolicyPda(fromAta);
30165
+ const toPolicy = getAccountPolicyPda(toAta);
30166
+ toPolicyAccount = toPolicy;
30167
+ remainingAccounts.push(...[
30168
+ extraMetasAccount,
30169
+ fromPolicy,
30170
+ toPolicy,
30171
+ TRANSFER_HOOK_PROGRAM
30172
+ ]);
30173
+ }
30174
+ const tx = await this.base.mintProgram.methods.forceTransferTokens(amount).accounts({
30175
+ glamState: this.base.statePda,
30176
+ glamSigner,
30177
+ glamMint: this.base.mintPda,
30178
+ from,
30179
+ to,
30180
+ toPolicyAccount
30181
+ }).remainingAccounts(remainingAccounts.map((pubkey)=>({
30182
+ pubkey,
30183
+ isSigner: false,
30184
+ isWritable: false
30185
+ }))).preInstructions(preInstructions).transaction();
30186
+ return await this.base.intoVersionedTransaction(tx, txOptions);
30187
+ }
30188
+ constructor(base){
30189
+ this.base = base;
30190
+ }
30191
+ };
29989
30192
  let TxBuilder$1 = class TxBuilder {
29990
- async initialize(mintModel, accountType, txOptions = {}) {
30193
+ async initialize(mintModel, accountType, decimals, txOptions = {}) {
29991
30194
  if (!mintModel.name) {
29992
30195
  throw new Error("Mint name must be specified");
29993
30196
  }
29994
30197
  if (!mintModel.baseAssetMint) {
29995
30198
  throw new Error("Mint asset must be specified");
29996
30199
  }
29997
- // Set glam mint decimals to the same as deposit asset
29998
- const { mint } = await this.base.fetchMintAndTokenProgram(mintModel.baseAssetMint);
29999
- const glamMintDecimals = mint.decimals;
30200
+ // If decimals is not specified, set it to the same as the deposit asset
30201
+ if (decimals === null) {
30202
+ const { mint } = await this.base.fetchMintAndTokenProgram(mintModel.baseAssetMint);
30203
+ decimals = mint.decimals;
30204
+ }
30000
30205
  const stateInitKey = [
30001
30206
  ...Buffer.from(anchor__namespace.utils.sha256.hash(charsToName(mintModel.name))).subarray(0, 8)
30002
30207
  ];
@@ -30010,15 +30215,14 @@ let TxBuilder$1 = class TxBuilder {
30010
30215
  const glamApi = process.env.NEXT_PUBLIC_GLAM_API || process.env.GLAM_API || "https://api.glam.systems";
30011
30216
  mintModel.uri = `${glamApi}/v0/token/2022/mint?key=${this.base.mintPda}`;
30012
30217
  }
30013
- const tx = await this.base.mintProgram.methods.initializeMint(new MintIdlModel(mintModel), stateInitKey, accountType, glamMintDecimals).accounts({
30218
+ const tx = await this.base.mintProgram.methods.initializeMint(new MintIdlModel(mintModel), stateInitKey, accountType, decimals).accounts({
30014
30219
  glamState: this.base.statePda,
30015
30220
  signer: txOptions.signer || this.base.signer,
30016
30221
  newMint: this.base.mintPda,
30017
30222
  extraMetasAccount: this.base.extraMetasPda,
30018
30223
  baseAssetMint: mintModel.baseAssetMint
30019
30224
  }).transaction();
30020
- const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
30021
- return vTx;
30225
+ return await this.base.intoVersionedTransaction(tx, txOptions);
30022
30226
  }
30023
30227
  async update(mintModel, txOptions = {}) {
30024
30228
  const tx = await this.base.mintProgram.methods.updateMint(new MintIdlModel(mintModel)).accounts({
@@ -30120,11 +30324,10 @@ class MintClient {
30120
30324
  // in case users choose to use a non-helius RPC. Fall back to getHolders if
30121
30325
  // helius API key is not provided
30122
30326
  const heliusApiKey = process.env.NEXT_PUBLIC_HELIUS_API_KEY || process.env.HELIUS_API_KEY;
30123
- if (!heliusApiKey) {
30327
+ if (!heliusApiKey || this.base.cluster !== ClusterNetwork.Mainnet) {
30124
30328
  return await this.getHolders(showZeroBalance);
30125
30329
  }
30126
- const cluster = this.base.cluster === ClusterNetwork.Mainnet ? "mainnet" : "devnet";
30127
- const response = await fetch(`https://${cluster}.helius-rpc.com/?api-key=${heliusApiKey}`, {
30330
+ const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${heliusApiKey}`, {
30128
30331
  method: "POST",
30129
30332
  headers: {
30130
30333
  "Content-Type": "application/json"
@@ -30143,14 +30346,15 @@ class MintClient {
30143
30346
  });
30144
30347
  const data = await response.json();
30145
30348
  const { token_accounts: tokenAccounts } = data.result;
30349
+ const { mint, tokenProgram } = await this.base.fetchMintAndTokenProgram(this.base.mintPda);
30146
30350
  return tokenAccounts.map((ta)=>({
30147
30351
  owner: new web3_js.PublicKey(ta.owner),
30148
30352
  pubkey: new web3_js.PublicKey(ta.address),
30149
30353
  mint: this.base.mintPda,
30150
- programId: splToken.TOKEN_2022_PROGRAM_ID,
30151
- decimals: 9,
30354
+ programId: tokenProgram,
30355
+ decimals: mint.decimals,
30152
30356
  amount: ta.amount,
30153
- uiAmount: Number(ta.amount) / 10 ** 9,
30357
+ uiAmount: Number(ta.amount) / 10 ** mint.decimals,
30154
30358
  frozen: ta.frozen
30155
30359
  }));
30156
30360
  }
@@ -30171,6 +30375,7 @@ class MintClient {
30171
30375
  }
30172
30376
  ]
30173
30377
  });
30378
+ const { mint, tokenProgram } = await this.base.fetchMintAndTokenProgram(this.base.mintPda);
30174
30379
  return accounts.map((a)=>{
30175
30380
  const { pubkey, account } = a;
30176
30381
  const tokenAccount = splToken.unpackAccount(pubkey, account, splToken.TOKEN_2022_PROGRAM_ID);
@@ -30178,16 +30383,20 @@ class MintClient {
30178
30383
  owner: tokenAccount.owner,
30179
30384
  pubkey: tokenAccount.address,
30180
30385
  mint: tokenAccount.mint,
30181
- programId: splToken.TOKEN_2022_PROGRAM_ID,
30182
- decimals: 9,
30386
+ programId: tokenProgram,
30387
+ decimals: mint.decimals,
30183
30388
  amount: tokenAccount.amount.toString(),
30184
- uiAmount: Number(tokenAccount.amount) / 10 ** 9,
30389
+ uiAmount: Number(tokenAccount.amount) / 10 ** mint.decimals,
30185
30390
  frozen: tokenAccount.isFrozen
30186
30391
  };
30187
30392
  }).filter((ta)=>showZeroBalance || ta.uiAmount > 0);
30188
30393
  }
30189
30394
  async initialize(mintModel, accountType, txOptions = {}) {
30190
- const vTx = await this.txBuilder.initialize(mintModel, accountType, txOptions);
30395
+ const vTx = await this.txBuilder.initialize(mintModel, accountType, null, txOptions);
30396
+ return await this.base.sendAndConfirm(vTx);
30397
+ }
30398
+ async initializeWithDecimals(mintModel, accountType, decimals, txOptions = {}) {
30399
+ const vTx = await this.txBuilder.initialize(mintModel, accountType, decimals, txOptions);
30191
30400
  return await this.base.sendAndConfirm(vTx);
30192
30401
  }
30193
30402
  async update(mintModel, txOptions = {}) {
@@ -30218,15 +30427,35 @@ class MintClient {
30218
30427
  const vTx = await this.txBuilder.closeMint(txOptions);
30219
30428
  return await this.base.sendAndConfirm(vTx);
30220
30429
  }
30430
+ async mint(to, amount, unfreeze = false, txOptions = {}) {
30431
+ const vTx = await this.mintTxBuilder.mint(to, amount, unfreeze, txOptions);
30432
+ return await this.base.sendAndConfirm(vTx);
30433
+ }
30434
+ async burn(from, amount, unfreeze = false, txOptions = {}) {
30435
+ const vTx = await this.mintTxBuilder.burn(from, amount, unfreeze, txOptions);
30436
+ return await this.base.sendAndConfirm(vTx);
30437
+ }
30438
+ async createTokenAccount(owner, setFrozen, txOptions = {}) {
30439
+ const vTx = await this.mintTxBuilder.createTokenAccount(owner, setFrozen, txOptions);
30440
+ return await this.base.sendAndConfirm(vTx);
30441
+ }
30442
+ async setTokenAccountsStates(tokenAccounts, frozen, txOptions = {}) {
30443
+ const vTx = await this.mintTxBuilder.setTokenAccountsStates(tokenAccounts, frozen, txOptions);
30444
+ return await this.base.sendAndConfirm(vTx);
30445
+ }
30446
+ async forceTransfer(from, to, amount, unfreeze = false, txOptions = {}) {
30447
+ const vTx = await this.mintTxBuilder.forceTransfer(from, to, amount, unfreeze, txOptions);
30448
+ return await this.base.sendAndConfirm(vTx);
30449
+ }
30221
30450
  constructor(base){
30222
30451
  this.base = base;
30223
- // this.mintTxBuilder = new MintTxBuilder(base);
30452
+ this.mintTxBuilder = new MintTxBuilder(base);
30224
30453
  this.txBuilder = new TxBuilder$1(base);
30225
30454
  }
30226
30455
  }
30227
30456
 
30228
30457
  let TxBuilder = class TxBuilder {
30229
- async emergencyAccessUpdate(args, txOptions) {
30458
+ async emergencyAccessUpdate(args, txOptions = {}) {
30230
30459
  const glamSigner = txOptions.signer || this.base.signer;
30231
30460
  const tx = await this.base.protocolProgram.methods.emergencyAccessUpdate(new EmergencyAccessUpdateArgs(args)).accounts({
30232
30461
  glamState: this.base.statePda,
@@ -30234,6 +30463,13 @@ let TxBuilder = class TxBuilder {
30234
30463
  }).preInstructions(txOptions.preInstructions || []).transaction();
30235
30464
  return await this.base.intoVersionedTransaction(tx, txOptions);
30236
30465
  }
30466
+ async emergencyAccessUpdateIx(args, txOptions = {}) {
30467
+ const glamSigner = txOptions.signer || this.base.signer;
30468
+ return await this.base.protocolProgram.methods.emergencyAccessUpdate(new EmergencyAccessUpdateArgs(args)).accounts({
30469
+ glamState: this.base.statePda,
30470
+ glamSigner
30471
+ }).instruction();
30472
+ }
30237
30473
  async enableDisableProtocols(integrationProgram, protocolBitmask, setEnabled, txOptions) {
30238
30474
  const glamSigner = txOptions.signer || this.base.getSigner();
30239
30475
  const tx = await this.base.protocolProgram.methods.enableDisableProtocols(integrationProgram, protocolBitmask, setEnabled).accounts({
@@ -30250,6 +30486,13 @@ let TxBuilder = class TxBuilder {
30250
30486
  }).preInstructions(txOptions.preInstructions || []).transaction();
30251
30487
  return await this.base.intoVersionedTransaction(tx, txOptions);
30252
30488
  }
30489
+ async grantRevokeDelegatePermissionsIx(delegate, integrationProgram, protocolBitflag, permissionsBitmask, setGranted, txOptions = {}) {
30490
+ const glamSigner = txOptions.signer || this.base.getSigner();
30491
+ return await this.base.protocolProgram.methods.grantRevokeDelegatePermissions(delegate, integrationProgram, protocolBitflag, permissionsBitmask, setGranted).accounts({
30492
+ glamState: this.base.statePda,
30493
+ glamSigner
30494
+ }).instruction();
30495
+ }
30253
30496
  async setProtocolPolicy(integrationProgram, protocolBitflag, data, txOptions) {
30254
30497
  const glamSigner = txOptions.signer || this.base.getSigner();
30255
30498
  const tx = await this.base.protocolProgram.methods.setProtocolPolicy(integrationProgram, protocolBitflag, data).accounts({
@@ -30417,6 +30660,194 @@ class AccessClient {
30417
30660
  }
30418
30661
  }
30419
30662
 
30663
+ /**
30664
+ * Get protocol names from a bitmask for a given integration program
30665
+ * Uses the SDK's parseProtocolsBitmask function
30666
+ */ function getProtocolNamesFromBitmask(integrationProgram, bitmask) {
30667
+ const { protocols } = parseProtocolsBitmask(integrationProgram, bitmask);
30668
+ return protocols.map((p)=>p.name);
30669
+ }
30670
+ /**
30671
+ * Get permission names from a permissions bitmask for a protocol
30672
+ * Uses the SDK's parseProtocolPermissionsBitmask function
30673
+ */ function getPermissionNamesFromBitmask(integrationProgram, protocolBitflag, permissionsBitmask) {
30674
+ const { permissions } = parseProtocolPermissionsBitmask(integrationProgram, protocolBitflag, permissionsBitmask);
30675
+ return permissions.map((p)=>p.name);
30676
+ }
30677
+ /**
30678
+ * Compare current and staged integrationAcls and return the differences
30679
+ */ function compareIntegrationAcls(current, staged) {
30680
+ const added = [];
30681
+ const removed = [];
30682
+ const modified = [];
30683
+ const currentMap = new Map();
30684
+ (current || []).forEach((acl)=>{
30685
+ currentMap.set(acl.integrationProgram.toBase58(), acl);
30686
+ });
30687
+ const stagedMap = new Map();
30688
+ (staged || []).forEach((acl)=>{
30689
+ stagedMap.set(acl.integrationProgram.toBase58(), acl);
30690
+ });
30691
+ // Find added integrations
30692
+ stagedMap.forEach((stagedAcl, programId)=>{
30693
+ if (!currentMap.has(programId)) {
30694
+ added.push(stagedAcl);
30695
+ }
30696
+ });
30697
+ // Find removed integrations
30698
+ currentMap.forEach((currentAcl, programId)=>{
30699
+ if (!stagedMap.has(programId)) {
30700
+ removed.push(currentAcl);
30701
+ }
30702
+ });
30703
+ // Find modified integrations (changed bitmask)
30704
+ currentMap.forEach((currentAcl, programId)=>{
30705
+ const stagedAcl = stagedMap.get(programId);
30706
+ if (stagedAcl && currentAcl.protocolsBitmask !== stagedAcl.protocolsBitmask) {
30707
+ const currentProtocols = getProtocolNamesFromBitmask(currentAcl.integrationProgram, currentAcl.protocolsBitmask);
30708
+ const stagedProtocols = getProtocolNamesFromBitmask(stagedAcl.integrationProgram, stagedAcl.protocolsBitmask);
30709
+ const enabledProtocols = stagedProtocols.filter((p)=>!currentProtocols.includes(p));
30710
+ const disabledProtocols = currentProtocols.filter((p)=>!stagedProtocols.includes(p));
30711
+ modified.push({
30712
+ integrationProgram: currentAcl.integrationProgram,
30713
+ currentBitmask: currentAcl.protocolsBitmask,
30714
+ stagedBitmask: stagedAcl.protocolsBitmask,
30715
+ enabledProtocols,
30716
+ disabledProtocols
30717
+ });
30718
+ }
30719
+ });
30720
+ return {
30721
+ added,
30722
+ removed,
30723
+ modified
30724
+ };
30725
+ }
30726
+ /**
30727
+ * Compare current and staged delegateAcls and return the differences
30728
+ */ function compareDelegateAcls(current, staged) {
30729
+ const added = [];
30730
+ const removed = [];
30731
+ const modified = [];
30732
+ const currentMap = new Map();
30733
+ (current || []).forEach((acl)=>{
30734
+ currentMap.set(acl.pubkey.toBase58(), acl);
30735
+ });
30736
+ const stagedMap = new Map();
30737
+ (staged || []).forEach((acl)=>{
30738
+ stagedMap.set(acl.pubkey.toBase58(), acl);
30739
+ });
30740
+ // Find added delegates
30741
+ stagedMap.forEach((stagedAcl, pubkey)=>{
30742
+ if (!currentMap.has(pubkey)) {
30743
+ added.push(stagedAcl);
30744
+ }
30745
+ });
30746
+ // Find removed delegates
30747
+ currentMap.forEach((currentAcl, pubkey)=>{
30748
+ if (!stagedMap.has(pubkey)) {
30749
+ removed.push(currentAcl);
30750
+ }
30751
+ });
30752
+ // Find modified delegates
30753
+ currentMap.forEach((currentAcl, pubkey)=>{
30754
+ const stagedAcl = stagedMap.get(pubkey);
30755
+ if (!stagedAcl) return;
30756
+ const permissionChanges = [];
30757
+ // Create maps for easier comparison
30758
+ const currentPermissionsMap = new Map();
30759
+ currentAcl.integrationPermissions.forEach((intPerm)=>{
30760
+ const programId = intPerm.integrationProgram.toBase58();
30761
+ const protocolMap = new Map();
30762
+ intPerm.protocolPermissions.forEach((protPerm)=>{
30763
+ protocolMap.set(protPerm.protocolBitflag, protPerm.permissionsBitmask);
30764
+ });
30765
+ currentPermissionsMap.set(programId, protocolMap);
30766
+ });
30767
+ const stagedPermissionsMap = new Map();
30768
+ stagedAcl.integrationPermissions.forEach((intPerm)=>{
30769
+ const programId = intPerm.integrationProgram.toBase58();
30770
+ const protocolMap = new Map();
30771
+ intPerm.protocolPermissions.forEach((protPerm)=>{
30772
+ protocolMap.set(protPerm.protocolBitflag, protPerm.permissionsBitmask);
30773
+ });
30774
+ stagedPermissionsMap.set(programId, protocolMap);
30775
+ });
30776
+ // Check all integration programs and protocols
30777
+ const allProgramIds = new Set([
30778
+ ...currentPermissionsMap.keys(),
30779
+ ...stagedPermissionsMap.keys()
30780
+ ]);
30781
+ allProgramIds.forEach((programId)=>{
30782
+ const currentProtocols = currentPermissionsMap.get(programId) || new Map();
30783
+ const stagedProtocols = stagedPermissionsMap.get(programId) || new Map();
30784
+ const integrationProgram = new web3_js.PublicKey(programId);
30785
+ const allProtocolBitflags = new Set([
30786
+ ...currentProtocols.keys(),
30787
+ ...stagedProtocols.keys()
30788
+ ]);
30789
+ allProtocolBitflags.forEach((protocolBitflag)=>{
30790
+ const current = currentProtocols.get(protocolBitflag);
30791
+ const staged = stagedProtocols.get(protocolBitflag);
30792
+ if (!current && staged) {
30793
+ // Protocol permissions added
30794
+ const protocolNames = getProtocolNamesFromBitmask(integrationProgram, protocolBitflag);
30795
+ const addedPermissions = getPermissionNamesFromBitmask(integrationProgram, protocolBitflag, staged);
30796
+ if (addedPermissions.length > 0) {
30797
+ permissionChanges.push({
30798
+ integrationProgram,
30799
+ protocolName: protocolNames[0] || "Unknown",
30800
+ addedPermissions,
30801
+ removedPermissions: []
30802
+ });
30803
+ }
30804
+ } else if (current && !staged) {
30805
+ // Protocol permissions removed
30806
+ const protocolNames = getProtocolNamesFromBitmask(integrationProgram, protocolBitflag);
30807
+ const removedPermissions = getPermissionNamesFromBitmask(integrationProgram, protocolBitflag, current);
30808
+ if (removedPermissions.length > 0) {
30809
+ permissionChanges.push({
30810
+ integrationProgram,
30811
+ protocolName: protocolNames[0] || "Unknown",
30812
+ addedPermissions: [],
30813
+ removedPermissions
30814
+ });
30815
+ }
30816
+ } else if (current && staged && !current.eq(staged)) {
30817
+ // Protocol permissions modified
30818
+ const protocolNames = getProtocolNamesFromBitmask(integrationProgram, protocolBitflag);
30819
+ const currentPermissions = getPermissionNamesFromBitmask(integrationProgram, protocolBitflag, current);
30820
+ const stagedPermissions = getPermissionNamesFromBitmask(integrationProgram, protocolBitflag, staged);
30821
+ const addedPermissions = stagedPermissions.filter((p)=>!currentPermissions.includes(p));
30822
+ const removedPermissions = currentPermissions.filter((p)=>!stagedPermissions.includes(p));
30823
+ if (addedPermissions.length > 0 || removedPermissions.length > 0) {
30824
+ permissionChanges.push({
30825
+ integrationProgram,
30826
+ protocolName: protocolNames[0] || "Unknown",
30827
+ addedPermissions,
30828
+ removedPermissions
30829
+ });
30830
+ }
30831
+ }
30832
+ });
30833
+ });
30834
+ // Check if there are any changes (expiration or permissions)
30835
+ if (!currentAcl.expiresAt.eq(stagedAcl.expiresAt) || permissionChanges.length > 0) {
30836
+ modified.push({
30837
+ pubkey: currentAcl.pubkey,
30838
+ currentExpiresAt: currentAcl.expiresAt,
30839
+ stagedExpiresAt: stagedAcl.expiresAt,
30840
+ permissionChanges
30841
+ });
30842
+ }
30843
+ });
30844
+ return {
30845
+ added,
30846
+ removed,
30847
+ modified
30848
+ };
30849
+ }
30850
+
30420
30851
  const getPriorityFeeEstimate = async (heliusApiKey, tx, accountKeys, priorityLevel)=>{
30421
30852
  if (!tx && !accountKeys) {
30422
30853
  throw new Error("Either tx or accountKeys must be provided");
@@ -30541,13 +30972,10 @@ exports.GLAM_REFERRER = GLAM_REFERRER;
30541
30972
  exports.GOVERNANCE_PROGRAM_ID = GOVERNANCE_PROGRAM_ID;
30542
30973
  exports.GlamClient = GlamClient;
30543
30974
  exports.GlamError = GlamError;
30544
- exports.GlamIntegrations = GlamIntegrations;
30545
30975
  exports.GlamMintIdl = GlamMintIdl;
30546
30976
  exports.GlamMintIdlJson = GlamMintIdlJson;
30547
- exports.GlamPermissions = GlamPermissions;
30548
30977
  exports.GlamProtocolIdl = GlamProtocolIdl;
30549
30978
  exports.GlamProtocolIdlJson = GlamProtocolIdlJson;
30550
- exports.INTEGRATION_MAPPING = INTEGRATION_MAPPING;
30551
30979
  exports.InsuranceFundOperation = InsuranceFundOperation;
30552
30980
  exports.IntegrationAcl = IntegrationAcl;
30553
30981
  exports.IntegrationPermissions = IntegrationPermissions;
@@ -30565,6 +30993,8 @@ exports.KAMINO_LENDING_PROGRAM = KAMINO_LENDING_PROGRAM;
30565
30993
  exports.KAMINO_OBTRIGATION_SIZE = KAMINO_OBTRIGATION_SIZE;
30566
30994
  exports.KAMINO_SCOPE_PRICES = KAMINO_SCOPE_PRICES;
30567
30995
  exports.KAMINO_VAULTS_PROGRAM = KAMINO_VAULTS_PROGRAM;
30996
+ exports.KaminoLendingPolicy = KaminoLendingPolicy;
30997
+ exports.KaminoVaultsPolicy = KaminoVaultsPolicy;
30568
30998
  exports.LPAction = LPAction;
30569
30999
  exports.LiquidationType = LiquidationType;
30570
31000
  exports.MARINADE_NATIVE_STAKE_AUTHORITY = MARINADE_NATIVE_STAKE_AUTHORITY;
@@ -30589,8 +31019,9 @@ exports.OrderActionExplanation = OrderActionExplanation;
30589
31019
  exports.OrderStatus = OrderStatus;
30590
31020
  exports.OrderTriggerCondition = OrderTriggerCondition;
30591
31021
  exports.OrderType = OrderType;
30592
- exports.PERMISSION_MAPPINGS = PERMISSION_MAPPINGS;
31022
+ exports.PROGRAM_AND_BITFLAG_BY_PROTOCOL_NAME = PROGRAM_AND_BITFLAG_BY_PROTOCOL_NAME;
30593
31023
  exports.PROTOCOLS_AND_PERMISSIONS = PROTOCOLS_AND_PERMISSIONS;
31024
+ exports.PROTOCOL_NAME_BY_PROGRAM_AND_BITFLAG = PROTOCOL_NAME_BY_PROGRAM_AND_BITFLAG;
30594
31025
  exports.PerpOperation = PerpOperation;
30595
31026
  exports.PlaceAndTakeOrderSuccessCondition = PlaceAndTakeOrderSuccessCondition;
30596
31027
  exports.PositionDirection = PositionDirection;
@@ -30642,6 +31073,8 @@ exports.WSOL = WSOL;
30642
31073
  exports.ZERO = ZERO;
30643
31074
  exports.bytesToHex = bytesToHex;
30644
31075
  exports.charsToName = charsToName;
31076
+ exports.compareDelegateAcls = compareDelegateAcls;
31077
+ exports.compareIntegrationAcls = compareIntegrationAcls;
30645
31078
  exports.decodeUser = decodeUser;
30646
31079
  exports.evmAddressToBytes32 = evmAddressToBytes32;
30647
31080
  exports.evmAddressToPublicKey = evmAddressToPublicKey;
@@ -30668,9 +31101,11 @@ exports.getMarketOrderParams = getMarketOrderParams;
30668
31101
  exports.getMintPda = getMintPda;
30669
31102
  exports.getOpenfundsPda = getOpenfundsPda;
30670
31103
  exports.getOrderParams = getOrderParams;
31104
+ exports.getPermissionNamesFromBitmask = getPermissionNamesFromBitmask;
30671
31105
  exports.getPriorityFeeEstimate = getPriorityFeeEstimate;
30672
31106
  exports.getProgramAccountsV2 = getProgramAccountsV2;
30673
31107
  exports.getProgramAccountsWithRetry = getProgramAccountsWithRetry;
31108
+ exports.getProtocolNamesFromBitmask = getProtocolNamesFromBitmask;
30674
31109
  exports.getQuoteResponse = getQuoteResponse;
30675
31110
  exports.getRequestQueuePda = getRequestQueuePda;
30676
31111
  exports.getSimulationResult = getSimulationResult;