@glamsystems/glam-sdk 0.1.16 → 0.1.18

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
@@ -4,12 +4,12 @@ var anchor = require('@coral-xyz/anchor');
4
4
  var web3_js = require('@solana/web3.js');
5
5
  var splToken = require('@solana/spl-token');
6
6
  var splTokenMetadata = require('@solana/spl-token-metadata');
7
+ var DLMM = require('@meteora-ag/dlmm');
7
8
  var bytes = require('@coral-xyz/anchor/dist/cjs/utils/bytes');
8
9
  var sdk = require('@drift-labs/sdk');
9
10
  var marinadeTsSdk = require('@marinade.finance/marinade-ts-sdk');
10
11
  var splStakePool = require('@solana/spl-stake-pool');
11
12
  var borsh = require('@coral-xyz/borsh');
12
- var DLMM = require('@meteora-ag/dlmm');
13
13
 
14
14
  function _interopNamespaceDefault(e) {
15
15
  var n = Object.create(null);
@@ -34,7 +34,7 @@ var borsh__namespace = /*#__PURE__*/_interopNamespaceDefault(borsh);
34
34
  var address = "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc";
35
35
  var metadata = {
36
36
  name: "glam_protocol",
37
- version: "0.4.13",
37
+ version: "0.4.16",
38
38
  spec: "0.1.0",
39
39
  description: "Glam Protocol"
40
40
  };
@@ -1280,6 +1280,144 @@ var instructions = [
1280
1280
  }
1281
1281
  ]
1282
1282
  },
1283
+ {
1284
+ name: "drift_settle_multiple_pnls",
1285
+ discriminator: [
1286
+ 100,
1287
+ 72,
1288
+ 3,
1289
+ 45,
1290
+ 69,
1291
+ 37,
1292
+ 10,
1293
+ 144
1294
+ ],
1295
+ accounts: [
1296
+ {
1297
+ name: "glam_state"
1298
+ },
1299
+ {
1300
+ name: "glam_vault",
1301
+ pda: {
1302
+ seeds: [
1303
+ {
1304
+ kind: "const",
1305
+ value: [
1306
+ 118,
1307
+ 97,
1308
+ 117,
1309
+ 108,
1310
+ 116
1311
+ ]
1312
+ },
1313
+ {
1314
+ kind: "account",
1315
+ path: "glam_state"
1316
+ }
1317
+ ]
1318
+ }
1319
+ },
1320
+ {
1321
+ name: "glam_signer",
1322
+ writable: true,
1323
+ signer: true
1324
+ },
1325
+ {
1326
+ name: "cpi_program",
1327
+ address: "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
1328
+ },
1329
+ {
1330
+ name: "state"
1331
+ },
1332
+ {
1333
+ name: "user",
1334
+ writable: true
1335
+ },
1336
+ {
1337
+ name: "spot_market_vault"
1338
+ }
1339
+ ],
1340
+ args: [
1341
+ {
1342
+ name: "market_indexes",
1343
+ type: {
1344
+ vec: "u16"
1345
+ }
1346
+ },
1347
+ {
1348
+ name: "mode",
1349
+ type: {
1350
+ defined: {
1351
+ name: "SettlePnlMode"
1352
+ }
1353
+ }
1354
+ }
1355
+ ]
1356
+ },
1357
+ {
1358
+ name: "drift_settle_pnl",
1359
+ discriminator: [
1360
+ 161,
1361
+ 254,
1362
+ 255,
1363
+ 100,
1364
+ 140,
1365
+ 113,
1366
+ 169,
1367
+ 175
1368
+ ],
1369
+ accounts: [
1370
+ {
1371
+ name: "glam_state"
1372
+ },
1373
+ {
1374
+ name: "glam_vault",
1375
+ pda: {
1376
+ seeds: [
1377
+ {
1378
+ kind: "const",
1379
+ value: [
1380
+ 118,
1381
+ 97,
1382
+ 117,
1383
+ 108,
1384
+ 116
1385
+ ]
1386
+ },
1387
+ {
1388
+ kind: "account",
1389
+ path: "glam_state"
1390
+ }
1391
+ ]
1392
+ }
1393
+ },
1394
+ {
1395
+ name: "glam_signer",
1396
+ writable: true,
1397
+ signer: true
1398
+ },
1399
+ {
1400
+ name: "cpi_program",
1401
+ address: "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
1402
+ },
1403
+ {
1404
+ name: "state"
1405
+ },
1406
+ {
1407
+ name: "user",
1408
+ writable: true
1409
+ },
1410
+ {
1411
+ name: "spot_market_vault"
1412
+ }
1413
+ ],
1414
+ args: [
1415
+ {
1416
+ name: "market_index",
1417
+ type: "u16"
1418
+ }
1419
+ ]
1420
+ },
1283
1421
  {
1284
1422
  name: "drift_update_user_custom_margin_ratio",
1285
1423
  discriminator: [
@@ -3095,6 +3233,96 @@ var instructions = [
3095
3233
  ],
3096
3234
  args: []
3097
3235
  },
3236
+ {
3237
+ name: "kamino_farm_harvest_reward",
3238
+ discriminator: [
3239
+ 64,
3240
+ 132,
3241
+ 133,
3242
+ 175,
3243
+ 224,
3244
+ 147,
3245
+ 145,
3246
+ 119
3247
+ ],
3248
+ accounts: [
3249
+ {
3250
+ name: "glam_state"
3251
+ },
3252
+ {
3253
+ name: "glam_vault",
3254
+ pda: {
3255
+ seeds: [
3256
+ {
3257
+ kind: "const",
3258
+ value: [
3259
+ 118,
3260
+ 97,
3261
+ 117,
3262
+ 108,
3263
+ 116
3264
+ ]
3265
+ },
3266
+ {
3267
+ kind: "account",
3268
+ path: "glam_state"
3269
+ }
3270
+ ]
3271
+ }
3272
+ },
3273
+ {
3274
+ name: "glam_signer",
3275
+ writable: true,
3276
+ signer: true
3277
+ },
3278
+ {
3279
+ name: "cpi_program",
3280
+ address: "FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr"
3281
+ },
3282
+ {
3283
+ name: "user_state",
3284
+ writable: true
3285
+ },
3286
+ {
3287
+ name: "farm_state",
3288
+ writable: true
3289
+ },
3290
+ {
3291
+ name: "global_config"
3292
+ },
3293
+ {
3294
+ name: "reward_mint"
3295
+ },
3296
+ {
3297
+ name: "user_reward_ata",
3298
+ writable: true
3299
+ },
3300
+ {
3301
+ name: "rewards_vault",
3302
+ writable: true
3303
+ },
3304
+ {
3305
+ name: "rewards_treasury_vault",
3306
+ writable: true
3307
+ },
3308
+ {
3309
+ name: "farm_vaults_authority"
3310
+ },
3311
+ {
3312
+ name: "scope_prices",
3313
+ optional: true
3314
+ },
3315
+ {
3316
+ name: "token_program"
3317
+ }
3318
+ ],
3319
+ args: [
3320
+ {
3321
+ name: "reward_index",
3322
+ type: "u64"
3323
+ }
3324
+ ]
3325
+ },
3098
3326
  {
3099
3327
  name: "kamino_lending_borrow_obligation_liquidity_v2",
3100
3328
  discriminator: [
@@ -3173,7 +3401,8 @@ var instructions = [
3173
3401
  },
3174
3402
  {
3175
3403
  name: "referrer_token_state",
3176
- writable: true
3404
+ writable: true,
3405
+ optional: true
3177
3406
  },
3178
3407
  {
3179
3408
  name: "token_program"
@@ -3183,11 +3412,13 @@ var instructions = [
3183
3412
  },
3184
3413
  {
3185
3414
  name: "obligation_farm_user_state",
3186
- writable: true
3415
+ writable: true,
3416
+ optional: true
3187
3417
  },
3188
3418
  {
3189
3419
  name: "reserve_farm_state",
3190
- writable: true
3420
+ writable: true,
3421
+ optional: true
3191
3422
  },
3192
3423
  {
3193
3424
  name: "farms_program"
@@ -3281,7 +3512,8 @@ var instructions = [
3281
3512
  writable: true
3282
3513
  },
3283
3514
  {
3284
- name: "placeholder_user_destination_collateral"
3515
+ name: "placeholder_user_destination_collateral",
3516
+ optional: true
3285
3517
  },
3286
3518
  {
3287
3519
  name: "collateral_token_program"
@@ -3294,11 +3526,13 @@ var instructions = [
3294
3526
  },
3295
3527
  {
3296
3528
  name: "obligation_farm_user_state",
3297
- writable: true
3529
+ writable: true,
3530
+ optional: true
3298
3531
  },
3299
3532
  {
3300
3533
  name: "reserve_farm_state",
3301
- writable: true
3534
+ writable: true,
3535
+ optional: true
3302
3536
  },
3303
3537
  {
3304
3538
  name: "farms_program"
@@ -3325,7 +3559,8 @@ var instructions = [
3325
3559
  ],
3326
3560
  accounts: [
3327
3561
  {
3328
- name: "glam_state"
3562
+ name: "glam_state",
3563
+ writable: true
3329
3564
  },
3330
3565
  {
3331
3566
  name: "glam_vault",
@@ -3546,7 +3781,8 @@ var instructions = [
3546
3781
  writable: true
3547
3782
  },
3548
3783
  {
3549
- name: "referrer_user_metadata"
3784
+ name: "referrer_user_metadata",
3785
+ optional: true
3550
3786
  },
3551
3787
  {
3552
3788
  name: "rent",
@@ -3641,11 +3877,13 @@ var instructions = [
3641
3877
  },
3642
3878
  {
3643
3879
  name: "obligation_farm_user_state",
3644
- writable: true
3880
+ writable: true,
3881
+ optional: true
3645
3882
  },
3646
3883
  {
3647
3884
  name: "reserve_farm_state",
3648
- writable: true
3885
+ writable: true,
3886
+ optional: true
3649
3887
  },
3650
3888
  {
3651
3889
  name: "lending_market_authority"
@@ -3742,7 +3980,8 @@ var instructions = [
3742
3980
  writable: true
3743
3981
  },
3744
3982
  {
3745
- name: "placeholder_user_destination_collateral"
3983
+ name: "placeholder_user_destination_collateral",
3984
+ optional: true
3746
3985
  },
3747
3986
  {
3748
3987
  name: "collateral_token_program"
@@ -3755,11 +3994,13 @@ var instructions = [
3755
3994
  },
3756
3995
  {
3757
3996
  name: "obligation_farm_user_state",
3758
- writable: true
3997
+ writable: true,
3998
+ optional: true
3759
3999
  },
3760
4000
  {
3761
4001
  name: "reserve_farm_state",
3762
- writable: true
4002
+ writable: true,
4003
+ optional: true
3763
4004
  },
3764
4005
  {
3765
4006
  name: "farms_program"
@@ -4280,7 +4521,8 @@ var instructions = [
4280
4521
  },
4281
4522
  {
4282
4523
  name: "bin_array_bitmap_extension",
4283
- writable: true
4524
+ writable: true,
4525
+ optional: true
4284
4526
  },
4285
4527
  {
4286
4528
  name: "user_token_x",
@@ -4392,7 +4634,8 @@ var instructions = [
4392
4634
  },
4393
4635
  {
4394
4636
  name: "bin_array_bitmap_extension",
4395
- writable: true
4637
+ writable: true,
4638
+ optional: true
4396
4639
  },
4397
4640
  {
4398
4641
  name: "user_token_x",
@@ -4504,7 +4747,8 @@ var instructions = [
4504
4747
  },
4505
4748
  {
4506
4749
  name: "bin_array_bitmap_extension",
4507
- writable: true
4750
+ writable: true,
4751
+ optional: true
4508
4752
  },
4509
4753
  {
4510
4754
  name: "user_token",
@@ -5061,7 +5305,8 @@ var instructions = [
5061
5305
  },
5062
5306
  {
5063
5307
  name: "bin_array_bitmap_extension",
5064
- writable: true
5308
+ writable: true,
5309
+ optional: true
5065
5310
  },
5066
5311
  {
5067
5312
  name: "user_token_x",
@@ -5178,7 +5423,8 @@ var instructions = [
5178
5423
  },
5179
5424
  {
5180
5425
  name: "bin_array_bitmap_extension",
5181
- writable: true
5426
+ writable: true,
5427
+ optional: true
5182
5428
  },
5183
5429
  {
5184
5430
  name: "user_token_x",
@@ -5292,7 +5538,8 @@ var instructions = [
5292
5538
  writable: true
5293
5539
  },
5294
5540
  {
5295
- name: "bin_array_bitmap_extension"
5541
+ name: "bin_array_bitmap_extension",
5542
+ optional: true
5296
5543
  },
5297
5544
  {
5298
5545
  name: "reserve_x",
@@ -5322,7 +5569,8 @@ var instructions = [
5322
5569
  },
5323
5570
  {
5324
5571
  name: "host_fee_in",
5325
- writable: true
5572
+ writable: true,
5573
+ optional: true
5326
5574
  },
5327
5575
  {
5328
5576
  name: "token_x_program"
@@ -5410,7 +5658,8 @@ var instructions = [
5410
5658
  writable: true
5411
5659
  },
5412
5660
  {
5413
- name: "bin_array_bitmap_extension"
5661
+ name: "bin_array_bitmap_extension",
5662
+ optional: true
5414
5663
  },
5415
5664
  {
5416
5665
  name: "reserve_x",
@@ -5440,7 +5689,8 @@ var instructions = [
5440
5689
  },
5441
5690
  {
5442
5691
  name: "host_fee_in",
5443
- writable: true
5692
+ writable: true,
5693
+ optional: true
5444
5694
  },
5445
5695
  {
5446
5696
  name: "token_x_program"
@@ -5613,7 +5863,8 @@ var instructions = [
5613
5863
  ],
5614
5864
  accounts: [
5615
5865
  {
5616
- name: "glam_state"
5866
+ name: "glam_state",
5867
+ writable: true
5617
5868
  },
5618
5869
  {
5619
5870
  name: "glam_vault"
@@ -5623,6 +5874,9 @@ var instructions = [
5623
5874
  writable: true,
5624
5875
  signer: true
5625
5876
  },
5877
+ {
5878
+ name: "sol_oracle"
5879
+ },
5626
5880
  {
5627
5881
  name: "state"
5628
5882
  },
@@ -5633,19 +5887,28 @@ var instructions = [
5633
5887
  name: "user_stats"
5634
5888
  }
5635
5889
  ],
5636
- args: []
5890
+ args: [
5891
+ {
5892
+ name: "denom",
5893
+ type: {
5894
+ defined: {
5895
+ name: "PriceDenom"
5896
+ }
5897
+ }
5898
+ }
5899
+ ]
5637
5900
  },
5638
5901
  {
5639
- name: "price_meteora",
5902
+ name: "price_kamino_obligations",
5640
5903
  discriminator: [
5641
5904
  166,
5642
- 250,
5643
- 203,
5644
- 148,
5645
- 67,
5646
- 60,
5647
- 207,
5648
- 51
5905
+ 110,
5906
+ 234,
5907
+ 179,
5908
+ 240,
5909
+ 179,
5910
+ 69,
5911
+ 246
5649
5912
  ],
5650
5913
  accounts: [
5651
5914
  {
@@ -5677,9 +5940,79 @@ var instructions = [
5677
5940
  name: "glam_signer",
5678
5941
  writable: true,
5679
5942
  signer: true
5943
+ },
5944
+ {
5945
+ name: "sol_oracle"
5680
5946
  }
5681
5947
  ],
5682
- args: []
5948
+ args: [
5949
+ {
5950
+ name: "denom",
5951
+ type: {
5952
+ defined: {
5953
+ name: "PriceDenom"
5954
+ }
5955
+ }
5956
+ }
5957
+ ]
5958
+ },
5959
+ {
5960
+ name: "price_meteora_positions",
5961
+ discriminator: [
5962
+ 186,
5963
+ 22,
5964
+ 157,
5965
+ 249,
5966
+ 185,
5967
+ 176,
5968
+ 253,
5969
+ 133
5970
+ ],
5971
+ accounts: [
5972
+ {
5973
+ name: "glam_state",
5974
+ writable: true
5975
+ },
5976
+ {
5977
+ name: "glam_vault",
5978
+ pda: {
5979
+ seeds: [
5980
+ {
5981
+ kind: "const",
5982
+ value: [
5983
+ 118,
5984
+ 97,
5985
+ 117,
5986
+ 108,
5987
+ 116
5988
+ ]
5989
+ },
5990
+ {
5991
+ kind: "account",
5992
+ path: "glam_state"
5993
+ }
5994
+ ]
5995
+ }
5996
+ },
5997
+ {
5998
+ name: "glam_signer",
5999
+ writable: true,
6000
+ signer: true
6001
+ },
6002
+ {
6003
+ name: "sol_oracle"
6004
+ }
6005
+ ],
6006
+ args: [
6007
+ {
6008
+ name: "denom",
6009
+ type: {
6010
+ defined: {
6011
+ name: "PriceDenom"
6012
+ }
6013
+ }
6014
+ }
6015
+ ]
5683
6016
  },
5684
6017
  {
5685
6018
  name: "price_stakes",
@@ -5723,9 +6056,21 @@ var instructions = [
5723
6056
  name: "glam_signer",
5724
6057
  writable: true,
5725
6058
  signer: true
6059
+ },
6060
+ {
6061
+ name: "sol_oracle"
5726
6062
  }
5727
6063
  ],
5728
- args: []
6064
+ args: [
6065
+ {
6066
+ name: "denom",
6067
+ type: {
6068
+ defined: {
6069
+ name: "PriceDenom"
6070
+ }
6071
+ }
6072
+ }
6073
+ ]
5729
6074
  },
5730
6075
  {
5731
6076
  name: "price_tickets",
@@ -5769,9 +6114,21 @@ var instructions = [
5769
6114
  name: "glam_signer",
5770
6115
  writable: true,
5771
6116
  signer: true
6117
+ },
6118
+ {
6119
+ name: "sol_oracle"
5772
6120
  }
5773
6121
  ],
5774
- args: []
6122
+ args: [
6123
+ {
6124
+ name: "denom",
6125
+ type: {
6126
+ defined: {
6127
+ name: "PriceDenom"
6128
+ }
6129
+ }
6130
+ }
6131
+ ]
5775
6132
  },
5776
6133
  {
5777
6134
  name: "price_vault",
@@ -5815,9 +6172,21 @@ var instructions = [
5815
6172
  name: "glam_signer",
5816
6173
  writable: true,
5817
6174
  signer: true
6175
+ },
6176
+ {
6177
+ name: "sol_oracle"
5818
6178
  }
5819
6179
  ],
5820
- args: []
6180
+ args: [
6181
+ {
6182
+ name: "denom",
6183
+ type: {
6184
+ defined: {
6185
+ name: "PriceDenom"
6186
+ }
6187
+ }
6188
+ }
6189
+ ]
5821
6190
  },
5822
6191
  {
5823
6192
  name: "queued_redeem",
@@ -8911,21 +9280,26 @@ var errors = [
8911
9280
  },
8912
9281
  {
8913
9282
  code: 51103,
8914
- name: "UnpricedExternalAccounts",
9283
+ name: "ExternalAccountsNotPriced",
8915
9284
  msg: "Not all external vault accounts are priced"
8916
9285
  },
8917
9286
  {
8918
9287
  code: 51104,
9288
+ name: "VaultAssetsNotPriced",
9289
+ msg: "Not all vault assets are priced"
9290
+ },
9291
+ {
9292
+ code: 51105,
8919
9293
  name: "VaultNotPriced",
8920
9294
  msg: "No priced assets found"
8921
9295
  },
8922
9296
  {
8923
- code: 51105,
9297
+ code: 51106,
8924
9298
  name: "PositiveAumRequired",
8925
9299
  msg: "AUM must be positive"
8926
9300
  },
8927
9301
  {
8928
- code: 51106,
9302
+ code: 51107,
8929
9303
  name: "MathError",
8930
9304
  msg: "Math error"
8931
9305
  },
@@ -11070,6 +11444,9 @@ var types = [
11070
11444
  {
11071
11445
  name: "KaminoWithdraw"
11072
11446
  },
11447
+ {
11448
+ name: "KaminoClaim"
11449
+ },
11073
11450
  {
11074
11451
  name: "MeteoraDlmmPosition"
11075
11452
  },
@@ -11138,6 +11515,9 @@ var types = [
11138
11515
  },
11139
11516
  {
11140
11517
  name: "USD"
11518
+ },
11519
+ {
11520
+ name: "ASSET6"
11141
11521
  }
11142
11522
  ]
11143
11523
  }
@@ -11264,6 +11644,20 @@ var types = [
11264
11644
  ]
11265
11645
  }
11266
11646
  },
11647
+ {
11648
+ name: "SettlePnlMode",
11649
+ type: {
11650
+ kind: "enum",
11651
+ variants: [
11652
+ {
11653
+ name: "MustSettle"
11654
+ },
11655
+ {
11656
+ name: "TrySettle"
11657
+ }
11658
+ ]
11659
+ }
11660
+ },
11267
11661
  {
11268
11662
  name: "ShareClassField",
11269
11663
  type: {
@@ -12018,6 +12412,8 @@ const SEED_VAULT = (GlamProtocolIdlJson.constants.find((x)=>x.name === "SEED_VAU
12018
12412
  const SEED_ESCROW = (GlamProtocolIdlJson.constants.find((x)=>x.name === "SEED_ESCROW")?.value || "").replace(/"/g, "");
12019
12413
  const MARINADE_TICKET_SIZE = 88;
12020
12414
  const STAKE_ACCOUNT_SIZE = 200;
12415
+ const METEORA_POSITION_SIZE = 8120;
12416
+ const KAMINO_OBTRIGATION_SIZE = 3344;
12021
12417
  const JITO_TIP_DEFAULT = new web3_js.PublicKey("96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5");
12022
12418
  /**
12023
12419
  * Token mints. If no devnet version is defined, assume mainnet and devnet addresses are the same.
@@ -12044,6 +12440,10 @@ const GOVERNANCE_PROGRAM_ID = new web3_js.PublicKey("GovaE4iu227srtG2s3tZzB4RmWB
12044
12440
  const JUP_VOTE_PROGRAM = new web3_js.PublicKey("voTpe3tHQ7AjQHMapgSue2HJFAh2cGsdokqN3XqmVSj");
12045
12441
  const MERKLE_DISTRIBUTOR_PROGRAM = new web3_js.PublicKey("DiS3nNjFVMieMgmiQFm6wgJL7nevk4NrhXKLbtEH1Z2R");
12046
12442
  const TRANSFER_HOOK_PROGRAM = new web3_js.PublicKey("po1iCYakK3gHCLbuju4wGzFowTMpAJxkqK1iwUqMonY");
12443
+ const METEORA_DLMM_PROGRAM = new web3_js.PublicKey("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo");
12444
+ const KAMINO_LENDING_PROGRAM = new web3_js.PublicKey("KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD");
12445
+ const KAMINO_FARM_PROGRAM = new web3_js.PublicKey("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
12446
+ const MEMO_PROGRAM = new web3_js.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
12047
12447
  /**
12048
12448
  * Stake pools
12049
12449
  */ const JITO_STAKE_POOL = new web3_js.PublicKey("Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb");
@@ -12132,6 +12532,7 @@ class StateModel extends StateIdlModel {
12132
12532
  let stateModel = {
12133
12533
  id: statePda,
12134
12534
  name: stateAccount.name,
12535
+ enabled: stateAccount.enabled,
12135
12536
  uri: stateAccount.uri,
12136
12537
  accountType: stateAccount.accountType,
12137
12538
  metadata: stateAccount.metadata,
@@ -12153,7 +12554,7 @@ class StateModel extends StateIdlModel {
12153
12554
  if (new StateIdlModel({}).hasOwnProperty(name)) {
12154
12555
  // @ts-ignore
12155
12556
  stateModel[name] = value;
12156
- } else {
12557
+ } else if (process.env.NODE_ENV === "development") {
12157
12558
  console.warn(`State param ${name} not found in StateIdlModel`);
12158
12559
  }
12159
12560
  });
@@ -12361,14 +12762,22 @@ class DelegateAcl {
12361
12762
  this.expiresAt = obj.expiresAt ?? new anchor.BN(0);
12362
12763
  }
12363
12764
  }
12765
+ class PriceDenom {
12766
+ }
12767
+ PriceDenom.SOL = {
12768
+ sol: {}
12769
+ };
12770
+ PriceDenom.USD = {
12771
+ usd: {}
12772
+ };
12364
12773
 
12365
- exports.ClusterNetwork = void 0;
12366
- (function(ClusterNetwork) {
12774
+ var ClusterNetwork = /*#__PURE__*/ function(ClusterNetwork) {
12367
12775
  ClusterNetwork["Mainnet"] = "mainnet-beta";
12368
12776
  ClusterNetwork["Testnet"] = "testnet";
12369
12777
  ClusterNetwork["Devnet"] = "devnet";
12370
12778
  ClusterNetwork["Custom"] = "custom";
12371
- })(exports.ClusterNetwork || (exports.ClusterNetwork = {}));
12779
+ return ClusterNetwork;
12780
+ }({});
12372
12781
 
12373
12782
  const fetchStakeAccounts = async (connection, withdrawAuthority)=>{
12374
12783
  const accounts = await connection.getParsedProgramAccounts(web3_js.StakeProgram.programId, {
@@ -12400,6 +12809,67 @@ const fetchMarinadeTicketAccounts = async (connection, beneficiary)=>await conne
12400
12809
  }
12401
12810
  ]
12402
12811
  });
12812
+ const fetchKaminoObligations = async (connection, owner, market)=>{
12813
+ const accounts = await connection.getParsedProgramAccounts(KAMINO_LENDING_PROGRAM, {
12814
+ filters: [
12815
+ {
12816
+ dataSize: KAMINO_OBTRIGATION_SIZE
12817
+ },
12818
+ {
12819
+ memcmp: {
12820
+ offset: 64,
12821
+ bytes: owner.toBase58()
12822
+ }
12823
+ },
12824
+ ...market ? [
12825
+ {
12826
+ memcmp: {
12827
+ offset: 32,
12828
+ bytes: market.toBase58()
12829
+ }
12830
+ }
12831
+ ] : []
12832
+ ]
12833
+ });
12834
+ return accounts.map((a)=>a.pubkey);
12835
+ };
12836
+ const fetchMeteoraPositions = async (connection, owner)=>{
12837
+ const accounts = await connection.getParsedProgramAccounts(METEORA_DLMM_PROGRAM, {
12838
+ filters: [
12839
+ {
12840
+ dataSize: METEORA_POSITION_SIZE
12841
+ },
12842
+ {
12843
+ memcmp: {
12844
+ offset: 40,
12845
+ bytes: owner.toBase58()
12846
+ }
12847
+ }
12848
+ ]
12849
+ });
12850
+ return accounts.map((a)=>a.pubkey);
12851
+ };
12852
+ const parseMeteoraPosition = async (connection, position)=>{
12853
+ const positionAccountInfo = await connection.getAccountInfo(position);
12854
+ if (!positionAccountInfo) {
12855
+ throw new Error("Position not found");
12856
+ }
12857
+ const positionData = positionAccountInfo.data;
12858
+ const lbPair = new web3_js.PublicKey(positionData.subarray(8, 40));
12859
+ const lowerBinId = positionData.subarray(7912, 7916).readInt32LE();
12860
+ const upperBinId = positionData.subarray(7916, 7920).readInt32LE();
12861
+ const lowerBinArrayIndex = DLMM.binIdToBinArrayIndex(new anchor.BN(lowerBinId));
12862
+ const [binArrayLower] = DLMM.deriveBinArray(lbPair, lowerBinArrayIndex, METEORA_DLMM_PROGRAM);
12863
+ const upperBinArrayIndex = anchor.BN.max(lowerBinArrayIndex.add(new anchor.BN(1)), DLMM.binIdToBinArrayIndex(new anchor.BN(upperBinId)));
12864
+ const [binArrayUpper] = DLMM.deriveBinArray(lbPair, upperBinArrayIndex, METEORA_DLMM_PROGRAM);
12865
+ return {
12866
+ lbPair,
12867
+ lowerBinId,
12868
+ upperBinId,
12869
+ binArrayLower,
12870
+ binArrayUpper
12871
+ };
12872
+ };
12403
12873
  const getSimulationComputeUnits = async (connection, instructions, payer, lookupTables)=>{
12404
12874
  const testInstructions = [
12405
12875
  // Set an arbitrarily high number in simulation
@@ -12456,556 +12926,132 @@ const getErrorFromRPCResponse = (rpcResponse)=>{
12456
12926
  }
12457
12927
  };
12458
12928
 
12459
- /**
12460
- * Metadata for an asset for pricing
12461
- */ class AssetMeta {
12462
- }
12463
- /**
12464
- * We use sponsored feed listed on https://docs.pyth.network/price-feeds/sponsored-feeds/solana for popular tokens.
12465
- *
12466
- * For PYUSD, we use the price feed from Drift.
12467
- * For LSTs, we use the state account to calculate the price based on the number of SOLs locked.
12468
- */ const ASSETS_MAINNET = new Map([
12929
+ const ASSETS_MAINNET = new Map([
12469
12930
  [
12470
- // wSOL
12931
+ // SOL
12471
12932
  "So11111111111111111111111111111111111111112",
12472
12933
  {
12473
- pricingAccount: new web3_js.PublicKey("7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE"),
12474
- priceFeed: "ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d"
12475
- }
12476
- ],
12477
- [
12478
- // USDC
12479
- "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
12480
- {
12481
- pricingAccount: new web3_js.PublicKey("Dpw1EAVrSB1ibxiDQyTAW6Zip3J4Btk2x4SgApQCeFbX"),
12482
- priceFeed: "eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"
12934
+ decimals: 9,
12935
+ oracle: new web3_js.PublicKey("3m6i4RFWEDw2Ft4tFHPJtYgmpPe21k56M3FHeWYrgGBz")
12483
12936
  }
12484
12937
  ],
12485
12938
  [
12486
- // USDT
12487
- "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
12488
- {
12489
- pricingAccount: new web3_js.PublicKey("HT2PLQBcG5EiCcNSaMHAjSgd9F98ecpATbk4Sk5oYuM"),
12490
- priceFeed: "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b"
12491
- }
12492
- ],
12493
- [
12494
- // wBTC (Wormhole)
12939
+ // wBTC
12495
12940
  "3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh",
12496
12941
  {
12497
- pricingAccount: new web3_js.PublicKey("9gNX5vguzarZZPjTnE1hWze3s6UsZ7dsU3UnAmKPnMHG"),
12498
- priceFeed: "c9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33"
12499
- }
12500
- ],
12501
- [
12502
- // ETH
12503
- "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
12504
- {
12505
- pricingAccount: new web3_js.PublicKey("42amVS4KgzR9rA28tkVYqVXjq9Qa8dcZQMbH5EYFX6XC"),
12506
- priceFeed: "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace"
12942
+ decimals: 8,
12943
+ oracle: new web3_js.PublicKey("fqPfDa6uQr9ndMvwaFp4mUBeUrHmLop8Jxfb1XJNmVm")
12507
12944
  }
12508
12945
  ],
12509
12946
  [
12510
- // PYTH
12511
- "HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3",
12947
+ // cbBTC
12948
+ "cbbtcf3aa214zXHbiAZQwf4122FBYbraNdFqgw4iMij",
12512
12949
  {
12513
- pricingAccount: new web3_js.PublicKey("8vjchtMuJNY4oFQdTi8yCe6mhCaNBFaUbktT482TpLPS"),
12514
- priceFeed: "0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff"
12950
+ decimals: 8,
12951
+ oracle: new web3_js.PublicKey("9jPy6EHpLkXaMdvfkoVnRnSdJoQysQDKKj3bW5Amz4Ci")
12515
12952
  }
12516
12953
  ],
12517
12954
  [
12518
- // BONK
12519
- "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
12955
+ // wETH
12956
+ "7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
12520
12957
  {
12521
- pricingAccount: new web3_js.PublicKey("DBE3N8uNjhKPRHfANdwGvCZghWXyLPdqdSbEW2XFwBiX"),
12522
- priceFeed: "72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419"
12958
+ decimals: 8,
12959
+ oracle: new web3_js.PublicKey("6bEp2MiyoiiiDxcVqE8rUHQWwHirXUXtKfAEATTVqNzT")
12523
12960
  }
12524
12961
  ],
12525
12962
  [
12526
- // mSOL
12527
- "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So",
12963
+ // JUP
12964
+ "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN",
12528
12965
  {
12529
- stateAccount: new web3_js.PublicKey("8szGkuLTAux9XMgZ2vtY39jVSowEcpBfFfD8hXSEqdGC"),
12530
- priceFeed: "c2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a4"
12966
+ decimals: 6,
12967
+ oracle: new web3_js.PublicKey("DXqKSHyhTBKEW4qgnL7ycbf3Jca5hCvUgWHFYWsh4KJa")
12531
12968
  }
12532
12969
  ],
12533
- //
12534
- // Price feed from Drift
12535
- //
12536
12970
  [
12537
- // PYUSD
12538
- "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
12971
+ // JLP
12972
+ "27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4",
12539
12973
  {
12540
- pricingAccount: new web3_js.PublicKey("HpMoKp3TCd3QT4MWYUKk2zCBwmhr5Df45fB6wdxYqEeh"),
12541
- priceFeed: "c1da1b73d7f01e7ddd54b3766cf7fcd644395ad14f70aa706ec5384c59e76692"
12974
+ decimals: 6,
12975
+ oracle: new web3_js.PublicKey("5Mb11e5rt1Sp6A286B145E4TmgMzsM2UX9nCF2vas5bs")
12542
12976
  }
12543
12977
  ],
12544
- //
12545
- // LST - autogen
12546
- //
12547
12978
  [
12548
- // fpSOL - FP SOL
12549
- "fpSoL8EJ7UA5yJxFKWk1MFiWi35w8CbH36G5B9d7DsV",
12979
+ // USDC
12980
+ "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
12550
12981
  {
12551
- stateAccount: new web3_js.PublicKey("GutG5bcmEZw15WmPHNVMWHU77c6t8CEinUEdPLYz3doa")
12982
+ decimals: 6,
12983
+ oracle: new web3_js.PublicKey("9VCioxmni2gDLv11qufWzT3RDERhQE4iY5Gf7NTfYyAV")
12552
12984
  }
12553
12985
  ],
12554
12986
  [
12555
- // wifSOL - dogwifSOL
12556
- "Fi5GayacZzUrfaCRCJtBz2vSYkGF56xjgCceZx5SbXwq",
12987
+ // USDT
12988
+ "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
12557
12989
  {
12558
- stateAccount: new web3_js.PublicKey("9Z8yimuc3bQCWLDyMhe6jfWqNk9EggyJZUo8TLnYsqhN")
12990
+ decimals: 6,
12991
+ oracle: new web3_js.PublicKey("JDKJSkxjasBGL3ce1pkrN6tqDzuVUZPWzzkGuyX8m9yN")
12559
12992
  }
12560
12993
  ],
12561
12994
  [
12562
- // pathSOL - Pathfinders SOL
12563
- "pathdXw4He1Xk3eX84pDdDZnGKEme3GivBamGCVPZ5a",
12995
+ // mSOL
12996
+ "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So",
12564
12997
  {
12565
- stateAccount: new web3_js.PublicKey("GM7TwD34n8HmDP9XcT6bD3JJuNniKJkrKQinHqmqHarz")
12998
+ decimals: 9,
12999
+ // oracle: new PublicKey("FAq7hqjn7FWGXKDwJHzsXGgBcydGTcK4kziJpAGWXjDb"), // drift pyth
13000
+ oracle: new web3_js.PublicKey("8szGkuLTAux9XMgZ2vtY39jVSowEcpBfFfD8hXSEqdGC")
12566
13001
  }
12567
13002
  ],
12568
13003
  [
12569
- // JupSOL - Jupiter Staked SOL
12570
- "jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v",
13004
+ // jitoSOL
13005
+ "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn",
12571
13006
  {
12572
- stateAccount: new web3_js.PublicKey("8VpRhuxa7sUUepdY3kQiTmX9rS5vx4WgaXiAnXq4KCtr")
13007
+ decimals: 9,
13008
+ // oracle: new PublicKey("9QE1P5EfzthYDgoQ9oPeTByCEKaRJeZbVVqKJfgU9iau"), // drift pyth
13009
+ oracle: new web3_js.PublicKey("Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb")
12573
13010
  }
12574
13011
  ],
12575
- // jjupSOL - Juicing Jupiter SOL
12576
- // [
12577
- // "BgYgFYq4A9a2o5S1QbWkmYVFBh7LBQL8YvugdhieFg38",
12578
- // {
12579
- // stateAccount: new PublicKey(
12580
- // "4mBwcXKJN2vz6MJikNTgVBSY5vYnyjZk7txd8j3K46Ei", // state
12581
- // ),
12582
- // },
12583
- // ],
12584
13012
  [
12585
- // phaseSOL - Phase Labs SOL
12586
- "phaseZSfPxTDBpiVb96H4XFSD8xHeHxZre5HerehBJG",
13013
+ // bonkSOL
13014
+ "BonK1YhkXEGLZzwtcvRTip3gAL9nCeQD7ppZBLXhtTs",
12587
13015
  {
12588
- stateAccount: new web3_js.PublicKey("phasejkG1akKgqkLvfWzWY17evnH6mSWznnUspmpyeG")
13016
+ decimals: 9,
13017
+ oracle: new web3_js.PublicKey("ArAQfbzsdotoKB5jJcZa3ajQrrPcWr2YQoDAEAiFxJAC")
12589
13018
  }
12590
13019
  ],
12591
13020
  [
12592
- // banxSOL - banxSOL
12593
- "BANXyWgPpa519e2MtQF1ecRbKYKKDMXPF1dyBxUq9NQG",
13021
+ // dSOL
13022
+ "Dso1bDeDjCQxTrWHqUUi63oBvV7Mdm6WaobLbQ7gnPQ",
12594
13023
  {
12595
- stateAccount: new web3_js.PublicKey("4fdMvFuyNboQ5Kr93X16f1tFcTeEkvfNwNAeSrzY3afb")
13024
+ decimals: 9,
13025
+ oracle: new web3_js.PublicKey("9mhGNSPArRMHpLDMSmxAvuoizBqtBGqYdT8WGuqgxNdn")
12596
13026
  }
12597
- ],
12598
- [
12599
- // iceSOL - iceSOL
12600
- "iceSdwqztAQFuH6En49HWwMxwthKMnGzLFQcMN3Bqhj",
12601
- {
12602
- stateAccount: new web3_js.PublicKey("EVXQHaLSJyUNrnBGfXUnvEi4DvVz4UJ3GnoKGVQVxrjr")
13027
+ ]
13028
+ ]);
13029
+ const ASSETS_TESTS = new Map([]);
13030
+ const SOL_ORACLE = ASSETS_MAINNET.get("So11111111111111111111111111111111111111112").oracle;
13031
+
13032
+ class GlamError extends Error {
13033
+ constructor(message, rawError, programLogs){
13034
+ super(message);
13035
+ this.message = message;
13036
+ this.rawError = rawError;
13037
+ this.programLogs = programLogs;
13038
+ }
13039
+ }
13040
+
13041
+ const BROWSER_CACHE_NAME = "glam-gui";
13042
+ class BlockhashWithCache {
13043
+ async get() {
13044
+ let data;
13045
+ if (this.isBrowser) {
13046
+ data = await this._getFromBrowserCache();
13047
+ } else {
13048
+ data = this._getFromNodeCache();
12603
13049
  }
12604
- ],
12605
- [
12606
- // fmSOL - SolanaFM Staked SOL
12607
- "fmSoLKzBY6h9b5RQ67UVs7xE3Ym6mx2ChpPxHdoaVho",
12608
- {
12609
- stateAccount: new web3_js.PublicKey("5FYTvZgc7QEGZSDmbJn5hrtjtRtyFZo5vR7gL1jJYanE")
12610
- }
12611
- ],
12612
- [
12613
- // BurnSOL - BurnDAO
12614
- "AxM7a5HNmRNHbND6h5ZMSsU8n3NLa1tskoN6m5mAgVvL",
12615
- {
12616
- stateAccount: new web3_js.PublicKey("CAEsfzw43mvaVauCxXCSJh8DvnFsTMiTyeL1kjs6UwaT")
12617
- }
12618
- ],
12619
- [
12620
- // BNSOL - Binance Staked SOL
12621
- "BNso1VUJnh4zcfpZa6986Ea66P6TCp59hvtNJ8b1X85",
12622
- {
12623
- stateAccount: new web3_js.PublicKey("Hr9pzexrBge3vgmBNRR8u42CNQgBXdHm4UkUN2DH4a7r")
12624
- }
12625
- ],
12626
- [
12627
- // pwrSOL - Power Staked SOL
12628
- "pWrSoLAhue6jUxUkbWgmEy5rD9VJzkFmvfTDV5KgNuu",
12629
- {
12630
- stateAccount: new web3_js.PublicKey("DfiQgSvpW3Dy4gKfhtdHnWGHwFUrE8exvaxqjtMtAVxk")
12631
- }
12632
- ],
12633
- [
12634
- // superSOL - Superfast Staked SOL
12635
- "suPer8CPwxoJPQ7zksGMwFvjBQhjAHwUMmPV4FVatBw",
12636
- {
12637
- stateAccount: new web3_js.PublicKey("4dZDUL3BFJUFeqS3Y3cwkc84Rs6mgVHRYGt1LJvhooW4")
12638
- }
12639
- ],
12640
- [
12641
- // jucySOL - Juicy SOL
12642
- "jucy5XJ76pHVvtPZb5TKRcGQExkwit2P5s4vY8UzmpC",
12643
- {
12644
- stateAccount: new web3_js.PublicKey("AZGSr2fUyKkPLMhAW6WUEKEsQiRMAFKf8Fjnt4MFFaGv")
12645
- }
12646
- ],
12647
- [
12648
- // bonkSOL - bonkSOL
12649
- "BonK1YhkXEGLZzwtcvRTip3gAL9nCeQD7ppZBLXhtTs",
12650
- {
12651
- stateAccount: new web3_js.PublicKey("ArAQfbzsdotoKB5jJcZa3ajQrrPcWr2YQoDAEAiFxJAC")
12652
- }
12653
- ],
12654
- [
12655
- // dSOL - Drift Staked SOL
12656
- "Dso1bDeDjCQxTrWHqUUi63oBvV7Mdm6WaobLbQ7gnPQ",
12657
- {
12658
- stateAccount: new web3_js.PublicKey("9mhGNSPArRMHpLDMSmxAvuoizBqtBGqYdT8WGuqgxNdn")
12659
- }
12660
- ],
12661
- [
12662
- // compassSOL - Compass SOL
12663
- "Comp4ssDzXcLeu2MnLuGNNFC4cmLPMng8qWHPvzAMU1h",
12664
- {
12665
- stateAccount: new web3_js.PublicKey("AwDeTcW6BovNYR34Df1TPm4bFwswa4CJY4YPye2LXtPS")
12666
- }
12667
- ],
12668
- [
12669
- // picoSOL - picoSOL
12670
- "picobAEvs6w7QEknPce34wAE4gknZA9v5tTonnmHYdX",
12671
- {
12672
- stateAccount: new web3_js.PublicKey("8Dv3hNYcEWEaa4qVx9BTN1Wfvtha1z8cWDUXb7KVACVe")
12673
- }
12674
- ],
12675
- [
12676
- // clockSOL - Overclock SOL
12677
- "GRJQtWwdJmp5LLpy8JWjPgn5FnLyqSJGNhn5ZnCTFUwM",
12678
- {
12679
- stateAccount: new web3_js.PublicKey("6e2LpgytfG3RqMdYuPr3dnedv6bmHQUk9hH9h2fzVk9o")
12680
- }
12681
- ],
12682
- [
12683
- // hubSOL - SolanaHub staked SOL
12684
- "HUBsveNpjo5pWqNkH57QzxjQASdTVXcSK7bVKTSZtcSX",
12685
- {
12686
- stateAccount: new web3_js.PublicKey("ECRqn7gaNASuvTyC5xfCUjehWZCSowMXstZiM5DNweyB")
12687
- }
12688
- ],
12689
- [
12690
- // strongSOL - Stronghold LST
12691
- "strng7mqqc1MBJJV6vMzYbEqnwVGvKKGKedeCvtktWA",
12692
- {
12693
- stateAccount: new web3_js.PublicKey("GZDX5JYXDzCEDL3kybhjN7PSixL4ams3M2G4CvWmMmm5")
12694
- }
12695
- ],
12696
- [
12697
- // lanternSOL - Lantern Staked SOL
12698
- "LnTRntk2kTfWEY6cVB8K9649pgJbt6dJLS1Ns1GZCWg",
12699
- {
12700
- stateAccount: new web3_js.PublicKey("LW3qEdGWdVrxNgxSXW8vZri7Jifg4HuKEQ1UABLxs3C")
12701
- }
12702
- ],
12703
- [
12704
- // stakeSOL - Stake City SOL
12705
- "st8QujHLPsX3d6HG9uQg9kJ91jFxUgruwsb1hyYXSNd",
12706
- {
12707
- stateAccount: new web3_js.PublicKey("2jjK1MsLgsPgVjnp97HUJeovNj3jp4XgyQ3nuiWMwiS8")
12708
- }
12709
- ],
12710
- [
12711
- // pumpkinSOL - Pumpkin's Staked SOL
12712
- "pumpkinsEq8xENVZE6QgTS93EN4r9iKvNxNALS1ooyp",
12713
- {
12714
- stateAccount: new web3_js.PublicKey("8WHCJsUduwDBhPL9uVADQSdWkUi2LPZNFAMyX1n2HGMD")
12715
- }
12716
- ],
12717
- [
12718
- // hSOL - Helius Staked SOL
12719
- "he1iusmfkpAdwvxLNGV8Y1iSbj4rUy6yMhEA3fotn9A",
12720
- {
12721
- stateAccount: new web3_js.PublicKey("3wK2g8ZdzAH8FJ7PKr2RcvGh7V9VYson5hrVsJM5Lmws")
12722
- }
12723
- ],
12724
- [
12725
- // lifSOL - Lifinity Staked SOL
12726
- "LSoLi4A4Pk4i8DPFYcfHziRdEbH9otvSJcSrkMVq99c",
12727
- {
12728
- stateAccount: new web3_js.PublicKey("HSDnqBq7EnfcKpnw52DTAZrP38tf8rdWLiRhQo4qGTUa")
12729
- }
12730
- ],
12731
- [
12732
- // cgntSOL - Cogent SOL
12733
- "CgnTSoL3DgY9SFHxcLj6CgCgKKoTBr6tp4CPAEWy25DE",
12734
- {
12735
- stateAccount: new web3_js.PublicKey("CgntPoLka5pD5fesJYhGmUCF8KU1QS1ZmZiuAuMZr2az")
12736
- }
12737
- ],
12738
- [
12739
- // laineSOL - Laine Stake Token
12740
- "LAinEtNLgpmCP9Rvsf5Hn8W6EhNiKLZQti1xfWMLy6X",
12741
- {
12742
- stateAccount: new web3_js.PublicKey("2qyEeSAWKfU18AFthrF7JA8z8ZCi1yt76Tqs917vwQTV")
12743
- }
12744
- ],
12745
- [
12746
- // vSOL - The Vault
12747
- "vSoLxydx6akxyMD9XEcPvGYNGq6Nn66oqVb3UkGkei7",
12748
- {
12749
- stateAccount: new web3_js.PublicKey("Fu9BYC6tWBo1KMKaP3CFoKfRhqv9akmy3DuYwnCyWiyC")
12750
- }
12751
- ],
12752
- [
12753
- // bSOL - BlazeStake Staked SOL
12754
- "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1",
12755
- {
12756
- stateAccount: new web3_js.PublicKey("stk9ApL5HeVAwPLr3TLhDXdZS8ptVu7zp6ov8HFDuMi")
12757
- }
12758
- ],
12759
- [
12760
- // daoSOL - daoSOL
12761
- "GEJpt3Wjmr628FqXxTgxMce1pLntcPV4uFi8ksxMyPQh",
12762
- {
12763
- stateAccount: new web3_js.PublicKey("7ge2xKsZXmqPxa3YmXxXmzCp9Hc2ezrTxh6PECaxCwrL")
12764
- }
12765
- ],
12766
- [
12767
- // JitoSOL - Jito Staked SOL
12768
- "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn",
12769
- {
12770
- stateAccount: new web3_js.PublicKey("Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb"),
12771
- pricingAccount: new web3_js.PublicKey("7yyaeuJ1GGtVBLT2z2xub5ZWYKaNhF28mj1RdV4VDFVk"),
12772
- priceFeed: "67be9f519b95cf24338801051f9a808eff0a578ccb388db73b7f6fe1de019ffb"
12773
- }
12774
- ],
12775
- [
12776
- // JSOL - JPOOL Solana Token
12777
- "7Q2afV64in6N6SeZsAAB81TJzwDoD6zpqmHkzi9Dcavn",
12778
- {
12779
- stateAccount: new web3_js.PublicKey("CtMyWsrUtAwXWiGr9WjHT5fC3p3fgV8cyGpLTo2LJzG1")
12780
- }
12781
- ],
12782
- [
12783
- // LST - Liquid Staking Token
12784
- "LSTxxxnJzKDFSLr4dUkPcmCf5VyryEqzPLz5j4bpxFp",
12785
- {
12786
- stateAccount: new web3_js.PublicKey("DqhH94PjkZsjAqEze2BEkWhFQJ6EyU6MdtMphMgnXqeK")
12787
- }
12788
- ],
12789
- [
12790
- // zippySOL - Zippy Staked SOL
12791
- "Zippybh3S5xYYam2nvL6hVJKz1got6ShgV4DyD1XQYF",
12792
- {
12793
- stateAccount: new web3_js.PublicKey("DxRFpqBQBC2nKcvh14gD1eizCj9Xi7ruMR3nCR3Hvw8f")
12794
- }
12795
- ],
12796
- [
12797
- // edgeSOL - Edgevana Staked SOL
12798
- "edge86g9cVz87xcpKpy3J77vbp4wYd9idEV562CCntt",
12799
- {
12800
- stateAccount: new web3_js.PublicKey("edgejNWAqkePLpi5sHRxT9vHi7u3kSHP9cocABPKiWZ")
12801
- }
12802
- ],
12803
- [
12804
- // thugSOL - Thugbirdz Staked SOL
12805
- "ThUGsoLWtoTCfb24AmQTKDVjTTUBbNrUrozupJeyPsy",
12806
- {
12807
- stateAccount: new web3_js.PublicKey("G9WdMBxWSo1X3fKxbuyGrv1nGXrVqGg5zBKAkBFkb37g")
12808
- }
12809
- ],
12810
- [
12811
- // wenSOL - Wen Staked SOL
12812
- "WensoLXxZJnev2YvihHFchn1dVVFnFLYvgomXWvvwRu",
12813
- {
12814
- stateAccount: new web3_js.PublicKey("CWM1VcNPd2A5WF2x2mmEUCgA1PGSKNZCGAH5GsoQw7h8")
12815
- }
12816
- ],
12817
- [
12818
- // camaoSOL - camaoSOL
12819
- "camaK1kryp4KJ2jS1HDiZuxmK7S6dyEtr9DA7NsuAAB",
12820
- {
12821
- stateAccount: new web3_js.PublicKey("2RUTyfN8iq7Hsd2s9rLgrRT9VhHLuqkx2mGNgbuzbhTc")
12822
- }
12823
- ],
12824
- [
12825
- // dainSOL - dainSOL
12826
- "2LuXDpkn7ZWMqufwgUv7ZisggGkSE5FpeHCHBsRgLg3m",
12827
- {
12828
- stateAccount: new web3_js.PublicKey("7qJ34Vq7nGZvk5YExkJsDZB6to6vz9RpcPmNEK84HjrV")
12829
- }
12830
- ],
12831
- [
12832
- // digitSOL - digitSOL
12833
- "D1gittVxgtszzY4fMwiTfM4Hp7uL5Tdi1S9LYaepAUUm",
12834
- {
12835
- stateAccount: new web3_js.PublicKey("4qYufFsPQETukkXd5z9fxDsdwm8AEaSqzYpuzmZzCJxR")
12836
- }
12837
- ],
12838
- [
12839
- // digitalSOL - digitalSOL
12840
- "3bfv2scCdbvumVBc3Sar5QhYXx7Ecsi8EFF2akjxe329",
12841
- {
12842
- stateAccount: new web3_js.PublicKey("Fwy2jGmRCDjKpWTacMVvnLp66Fg4L5yhVCfahHsbjMGf")
12843
- }
12844
- ],
12845
- [
12846
- // dlgtSOL - Delegate Liquid Staking SOL
12847
- "DLGToUUnqy9hXxpJTm5VaiBKqnw9Zt1qzvrpwKwUmuuZ",
12848
- {
12849
- stateAccount: new web3_js.PublicKey("9pffpv2w65TSeZpD988hAjvvzUiF1KZN1Swx5j2zPCdy")
12850
- }
12851
- ],
12852
- [
12853
- // dualSOL - Dual SOL
12854
- "DUAL6T9pATmQUFPYmrWq2BkkGdRxLtERySGScYmbHMER",
12855
- {
12856
- stateAccount: new web3_js.PublicKey("BmEgS5XpWJJDqT3FVfB6ZmoELQrWkJxDXo3cNoJVsNFK")
12857
- }
12858
- ],
12859
- [
12860
- // haSOL - Hanabi Staked SOL
12861
- "haSo1Vz5aTsqEnz8nisfnEsipvbAAWpgzRDh2WhhMEh",
12862
- {
12863
- stateAccount: new web3_js.PublicKey("9ovWYMZp18Qn7UVbyUvwqLSBBSEPDDA5q9pUgDFy6R23")
12864
- }
12865
- ],
12866
- [
12867
- // hausSOL - StakeHaus Staked SOL
12868
- "HausGKcq9G9zM3azwNmgZyzUvYeeqR8h8663PmZpxuDj",
12869
- {
12870
- stateAccount: new web3_js.PublicKey("5bzgfi7nidWWrp3DCwPwLzepw7PGgawRmMH9tqqXMZRj")
12871
- }
12872
- ],
12873
- [
12874
- // kumaSOL - kumaSOL
12875
- "KUMAgSzADhUmwXwNiUbNHYnMBnd89u4t9obZThJ4dqg",
12876
- {
12877
- stateAccount: new web3_js.PublicKey("Fvy5L7f3rduuYfRf9GR9fDqEgmJkYagDPh3Ddkp5jcoP")
12878
- }
12879
- ],
12880
- [
12881
- // nordSOL - Nordic Staked SOL
12882
- "nordEhq2BnR6weCyrdezNVk7TwC3Ej94znPZxdBnfLM",
12883
- {
12884
- stateAccount: new web3_js.PublicKey("GrrASJmjz19gHDsUUGv9y3gtRAwYJcdrtFESCRAosd44")
12885
- }
12886
- ],
12887
- [
12888
- // polarSOL - polarSOL
12889
- "PoLaRbHgtHnmeSohWQN83LkwA4xnQt91VUqL5hx5VTc",
12890
- {
12891
- stateAccount: new web3_js.PublicKey("EYwMHf8Ajnpvy3PqMMkq1MPkTyhCsBEesXFgnK9BZfmu")
12892
- }
12893
- ],
12894
- [
12895
- // rkSOL - StaRKe SOL
12896
- "EPCz5LK372vmvCkZH3HgSuGNKACJJwwxsofW6fypCPZL",
12897
- {
12898
- stateAccount: new web3_js.PublicKey("6LXCxeyQZqdAL4yLCtgATFYF6dcayWvsiwjtBFYVfb1N")
12899
- }
12900
- ],
12901
- [
12902
- // rSOL - reflectSOL
12903
- "RSoLp7kddnNwvvvaz4b1isQy8vcqdSwXjgm1wXaMhD8",
12904
- {
12905
- stateAccount: new web3_js.PublicKey("4gT1GaFtJK5pnX3CnjnSYwy8VUV9UdmozoQV9GCNk9RQ")
12906
- }
12907
- ],
12908
- [
12909
- // spikySOL - Hedgehog Spiky SOL
12910
- "spkyB5SzVaz2x3nNzSBuhpLSEF8otbRDbufc73fuLXg",
12911
- {
12912
- stateAccount: new web3_js.PublicKey("GEGRQNw17Y5s44dRH69sk8bvhyj3i6VwgqGmN1MBHKHp")
12913
- }
12914
- ],
12915
- [
12916
- // stakrSOL - STAKR.space SOL
12917
- "stkrHcjQGytQggswj3tCF77yriaJYYhrRxisRqe9AiZ",
12918
- {
12919
- stateAccount: new web3_js.PublicKey("9j2mFdABTCCnWnzLtpMjp86AEcm4e3XistVeuujds7Au")
12920
- }
12921
- ],
12922
- [
12923
- // xSOL - ElagabalX Staked SOL
12924
- "B5GgNAZQDN8vPrQ15jPrXmJxVtManHLqHogj9B9i4zSs",
12925
- {
12926
- stateAccount: new web3_js.PublicKey("DYuSikgwzHidFo2b8jqrViW1psAb7hpawJnszBothRzp")
12927
- }
12928
- ],
12929
- [
12930
- // fuseSOL - Fuse Staked SOL
12931
- "fuseYvhNJbSzdDByyTCrLcogsoNwAviB1WeewhbqgFc",
12932
- {
12933
- stateAccount: new web3_js.PublicKey("pjwKqvtt4ij6VJW4HxNxSaufSrkWHRc6iCTHoC4gFs4")
12934
- }
12935
- ],
12936
- [
12937
- // mangoSOL - Mango SOL
12938
- "MangmsBgFqJhW4cLUR9LxfVgMboY1xAoP8UUBiWwwuY",
12939
- {
12940
- stateAccount: new web3_js.PublicKey("9jWbABPXfc75wseAbLEkBCb1NRaX9EbJZJTDQnbtpzc1")
12941
- }
12942
- ],
12943
- [
12944
- // apySOL - apySOL
12945
- "apySoLhdVa6QbvNyEjXCbET3FdUm9cCdEvYyjCU7icM",
12946
- {
12947
- stateAccount: new web3_js.PublicKey("FxhzbU8rn4MhZxmeH2u7M18qkvFH3LjkWk8z9686TE45")
12948
- }
12949
- ],
12950
- [
12951
- // bbSOL
12952
- "Bybit2vBJGhPF52GBdNaQfUJ6ZpThSgHBobjWZpLPb4B",
12953
- {
12954
- stateAccount: new web3_js.PublicKey("2aMLkB5p5gVvCwKkdSo5eZAL1WwhZbxezQr1wxiynRhq")
12955
- }
12956
- ]
12957
- ]);
12958
- const ASSETS_TESTS = new Map([
12959
- //
12960
- // LOCALNET
12961
- //
12962
- [
12963
- // USDC
12964
- "AwRP1kuJbykXeF4hcLzfMDMY2ZTGN3cx8ErCWxVYekef",
12965
- {
12966
- pricingAccount: new web3_js.PublicKey("Dpw1EAVrSB1ibxiDQyTAW6Zip3J4Btk2x4SgApQCeFbX")
12967
- }
12968
- ],
12969
- [
12970
- // BTC
12971
- "7Pz5yQdyQm64WtzxvpQZi3nD1q5mbxj4Hhcjy2kmZ7Zd",
12972
- {
12973
- pricingAccount: new web3_js.PublicKey("4cSM2e6rvbGQUFiJbqytoVMi5GgghSMr8LwVrT9VPSPo"),
12974
- programId: splToken.TOKEN_2022_PROGRAM_ID
12975
- }
12976
- ],
12977
- [
12978
- // ETH
12979
- "GRxagtBNxzjwxkKdEgW7P1oqU57Amai6ha5F3UBJzU1m",
12980
- {
12981
- pricingAccount: new web3_js.PublicKey("42amVS4KgzR9rA28tkVYqVXjq9Qa8dcZQMbH5EYFX6XC")
12982
- }
12983
- ]
12984
- ]);
12985
-
12986
- class GlamError extends Error {
12987
- constructor(message, rawError, programLogs){
12988
- super(message);
12989
- this.message = message;
12990
- this.rawError = rawError;
12991
- this.programLogs = programLogs;
12992
- }
12993
- }
12994
-
12995
- const BROWSER_CACHE_NAME = "glam-gui";
12996
- class BlockhashWithCache {
12997
- async get() {
12998
- let data;
12999
- if (this.isBrowser) {
13000
- data = await this._getFromBrowserCache();
13001
- } else {
13002
- data = this._getFromNodeCache();
13003
- }
13004
- if (data) {
13005
- const { blockhash, expiresAt } = data;
13006
- if (expiresAt > Date.now()) {
13007
- return blockhash;
13008
- }
13050
+ if (data) {
13051
+ const { blockhash, expiresAt } = data;
13052
+ if (expiresAt > Date.now()) {
13053
+ return blockhash;
13054
+ }
13009
13055
  }
13010
13056
  const latestBlockhash = await this.provider.connection.getLatestBlockhash();
13011
13057
  await this.set({
@@ -13066,15 +13112,15 @@ class BaseClient {
13066
13112
  get detectedCluster() {
13067
13113
  const rpcUrl = this.provider.connection.rpcEndpoint;
13068
13114
  if (rpcUrl.includes("devnet")) {
13069
- return exports.ClusterNetwork.Devnet;
13115
+ return ClusterNetwork.Devnet;
13070
13116
  }
13071
13117
  if (rpcUrl.includes("localhost") || rpcUrl.includes("127.0.0.1")) {
13072
- return exports.ClusterNetwork.Custom;
13118
+ return ClusterNetwork.Custom;
13073
13119
  }
13074
- return exports.ClusterNetwork.Mainnet;
13120
+ return ClusterNetwork.Mainnet;
13075
13121
  }
13076
13122
  isMainnet() {
13077
- return this.cluster === exports.ClusterNetwork.Mainnet;
13123
+ return this.cluster === ClusterNetwork.Mainnet;
13078
13124
  }
13079
13125
  isPhantom() {
13080
13126
  if (!isBrowser) return false;
@@ -13087,7 +13133,14 @@ class BaseClient {
13087
13133
  * @param assetMint Token mint of the asset
13088
13134
  * @returns Metadata of the asset
13089
13135
  */ getAssetMeta(assetMint) {
13090
- return (this.isMainnet() ? ASSETS_MAINNET.get(assetMint) : ASSETS_MAINNET.get(assetMint) || ASSETS_TESTS.get(assetMint)) || new AssetMeta();
13136
+ let assetMeta = ASSETS_MAINNET.get(assetMint);
13137
+ if (!assetMeta && !this.isMainnet()) {
13138
+ assetMeta = ASSETS_TESTS.get(assetMint);
13139
+ }
13140
+ if (!assetMeta) {
13141
+ throw new Error("Invalid asset: " + assetMint);
13142
+ }
13143
+ return assetMeta;
13091
13144
  }
13092
13145
  async getComputeBudgetIxs(vTx, computeUnitLimit, getPriorityFeeMicroLamports, maxFeeLamports, useMaxFee) {
13093
13146
  if (this.isPhantom()) {
@@ -13171,7 +13224,7 @@ class BaseClient {
13171
13224
  async sendAndConfirm(tx, additionalSigners = []) {
13172
13225
  const connection = this.provider.connection;
13173
13226
  // Mainnet only: use dedicated connection for sending transactions if available
13174
- const txConnection = this.cluster === exports.ClusterNetwork.Mainnet ? new web3_js.Connection(process.env?.NEXT_PUBLIC_TX_RPC || process.env.TX_RPC || connection.rpcEndpoint, {
13227
+ const txConnection = this.cluster === ClusterNetwork.Mainnet ? new web3_js.Connection(process.env?.NEXT_PUBLIC_TX_RPC || process.env.TX_RPC || connection.rpcEndpoint, {
13175
13228
  commitment: "confirmed"
13176
13229
  }) : connection;
13177
13230
  // This is just a convenient method so that in tests we can send legacy
@@ -13428,7 +13481,7 @@ class BaseClient {
13428
13481
  const solBalance = new anchor.BN(await this.provider.connection.getBalance(glamVault));
13429
13482
  const delta = new anchor.BN(lamports).sub(wsolBalance); // wSOL amount needed
13430
13483
  if (solBalance.lt(delta)) {
13431
- throw new Error("Insufficient funds in vault to complete the transaction");
13484
+ throw new Error(`Insufficient funds in vault to complete the transaction. SOL balance (lamports): ${solBalance}, lamports needed: ${lamports}`);
13432
13485
  }
13433
13486
  if (delta.gt(new anchor.BN(0)) && solBalance.gte(delta)) {
13434
13487
  return [
@@ -13547,7 +13600,7 @@ class DriftClient {
13547
13600
  /*
13548
13601
  * Client methods
13549
13602
  */ async initialize(statePda, subAccountId = 0, txOptions = {}) {
13550
- const tx = await this.initializeTx(statePda, subAccountId, txOptions);
13603
+ const tx = await this.initializeTx(new web3_js.PublicKey(statePda), subAccountId, txOptions);
13551
13604
  return await this.base.sendAndConfirm(tx);
13552
13605
  }
13553
13606
  async updateUserCustomMarginRatio(statePda, maxLeverage, subAccountId = 0) {
@@ -13590,8 +13643,12 @@ class DriftClient {
13590
13643
  const tx = await this.cancelOrdersByIdsTx(new web3_js.PublicKey(statePda), orderIds, subAccountId, marketConfigs, txOptions);
13591
13644
  return await this.base.sendAndConfirm(tx);
13592
13645
  }
13593
- async priceDrift(statePda, marketConfigs, txOptions = {}) {
13594
- const tx = await this.priceDriftTx(new web3_js.PublicKey(statePda), marketConfigs, txOptions);
13646
+ async settlePnl(statePda, marketIndex, subAccountId = 0, marketConfigs, txOptions = {}) {
13647
+ const tx = await this.settlePnlTx(new web3_js.PublicKey(statePda), marketIndex, subAccountId, marketConfigs, txOptions);
13648
+ return await this.base.sendAndConfirm(tx);
13649
+ }
13650
+ async priceDrift(statePda, marketConfigs, priceDenom, txOptions = {}) {
13651
+ const tx = await this.priceDriftTx(new web3_js.PublicKey(statePda), marketConfigs, priceDenom, txOptions);
13595
13652
  return await this.base.sendAndConfirm(tx);
13596
13653
  }
13597
13654
  /*
@@ -13702,17 +13759,20 @@ class DriftClient {
13702
13759
  userStats,
13703
13760
  state,
13704
13761
  glamSigner
13705
- })// .remainingAccounts([]) TODO: set glam referral account
13762
+ })// We should only try to add referrer if it is the first user (subAccountId == 0)
13763
+ // .remainingAccounts([]) TODO: set glam referral account
13706
13764
  .instruction();
13707
13765
  }
13708
13766
  async initializeTx(glamState, subAccountId = 0, txOptions = {}) {
13709
13767
  const glamSigner = txOptions.signer || this.base.getSigner();
13710
13768
  const tx = new web3_js.Transaction();
13711
- // Create userStats account first if subAccountId is 0
13712
- // If subAccountId > 0, we assume userStats account is already created
13713
- if (subAccountId === 0) {
13769
+ // Create userStats account if it doesn't exist
13770
+ const [_, userStats] = this.getUser(glamState);
13771
+ const userStatsInfo = await this.base.provider.connection.getAccountInfo(userStats);
13772
+ if (!userStatsInfo) {
13714
13773
  tx.add(await this.initializeUserStatsIx(glamState, glamSigner));
13715
13774
  }
13775
+ // Initialize user (aka sub-account)
13716
13776
  tx.add(await this.initializeUserIx(glamState, glamSigner, subAccountId));
13717
13777
  return await this.base.intoVersionedTransaction(tx, txOptions);
13718
13778
  }
@@ -13893,8 +13953,8 @@ class DriftClient {
13893
13953
  const [user] = this.getUser(glamState, subAccountId);
13894
13954
  const driftState = await sdk.getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
13895
13955
  const remainingAccounts = await this.composeRemainingAccounts(glamState, subAccountId, marketConfigs, marketType, marketIndex);
13896
- const tx = await this.base.program.methods// @ts-ignore
13897
- .driftCancelOrders(marketType, marketIndex, direction).accounts({
13956
+ // @ts-ignore
13957
+ const tx = await this.base.program.methods.driftCancelOrders(marketType, marketIndex, direction).accounts({
13898
13958
  glamState,
13899
13959
  glamSigner,
13900
13960
  user,
@@ -13915,18 +13975,33 @@ class DriftClient {
13915
13975
  }).remainingAccounts(remainingAccounts).transaction();
13916
13976
  return await this.base.intoVersionedTransaction(tx, txOptions);
13917
13977
  }
13918
- async priceDriftTx(glamState, marketConfigs, txOptions = {}) {
13978
+ async settlePnlTx(glamState, marketIndex, subAccountId = 0, marketConfigs, txOptions = {}) {
13979
+ const glamSigner = txOptions.signer || this.base.getSigner();
13980
+ const [user] = this.getUser(glamState, subAccountId);
13981
+ const driftState = await sdk.getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
13982
+ const { vaultPDA } = marketConfigs.spot[marketIndex];
13983
+ const tx = await this.base.program.methods.driftSettlePnl(marketIndex).accounts({
13984
+ glamState,
13985
+ glamSigner,
13986
+ user,
13987
+ state: driftState,
13988
+ spotMarketVault: new web3_js.PublicKey(vaultPDA)
13989
+ }).transaction();
13990
+ return await this.base.intoVersionedTransaction(tx, txOptions);
13991
+ }
13992
+ async priceDriftTx(glamState, marketConfigs, priceDenom, txOptions = {}) {
13919
13993
  const signer = txOptions.signer || this.base.getSigner();
13920
13994
  const glamVault = this.base.getVaultPda(glamState);
13921
13995
  const [user, userStats] = this.getUser(glamState);
13922
13996
  const driftState = await sdk.getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
13923
13997
  const remainingAccounts = await this.composeRemainingAccounts(glamState, 0, marketConfigs);
13924
- const tx = await this.base.program.methods.priceDrift().accounts({
13998
+ const tx = await this.base.program.methods.priceDrift(priceDenom).accounts({
13925
13999
  glamState,
13926
14000
  signer,
13927
14001
  glamVault,
13928
14002
  user,
13929
14003
  userStats,
14004
+ solOracle: SOL_ORACLE,
13930
14005
  state: driftState
13931
14006
  }).remainingAccounts(remainingAccounts).transaction();
13932
14007
  return await this.base.intoVersionedTransaction(tx, txOptions);
@@ -14007,8 +14082,8 @@ class JupiterSwapClient {
14007
14082
  this.getTokenProgram(inputMint),
14008
14083
  this.getTokenProgram(outputMint)
14009
14084
  ]);
14010
- const inputStakePool = ASSETS_MAINNET.get(inputMint.toBase58())?.stateAccount || null;
14011
- const outputStakePool = ASSETS_MAINNET.get(outputMint.toBase58())?.stateAccount || null;
14085
+ const inputStakePool = ASSETS_MAINNET.get(inputMint.toBase58())?.oracle || null;
14086
+ const outputStakePool = ASSETS_MAINNET.get(outputMint.toBase58())?.oracle || null;
14012
14087
  const preInstructions = await this.getPreInstructions(glamState, glamSigner, inputMint, outputMint, amount, inputTokenProgram, outputTokenProgram);
14013
14088
  // @ts-ignore
14014
14089
  const tx = await this.base.program.methods.jupiterSwap(swapIx.data).accounts({
@@ -14575,10 +14650,10 @@ class StakingClient {
14575
14650
  }
14576
14651
  // Other LSTs
14577
14652
  const assetMeta = this.base.getAssetMeta(assetStr);
14578
- if (!assetMeta || !assetMeta.stateAccount) {
14653
+ if (!assetMeta || !assetMeta.oracle) {
14579
14654
  throw new Error("Invalid LST: " + asset);
14580
14655
  }
14581
- const tx = await this.stakePoolWithdrawStakeTx(glamState, assetMeta.stateAccount, new anchor.BN(amount), true, txOptions);
14656
+ const tx = await this.stakePoolWithdrawStakeTx(glamState, assetMeta.oracle, new anchor.BN(amount), true, txOptions);
14582
14657
  return await this.base.sendAndConfirm(tx);
14583
14658
  }
14584
14659
  async stakePoolDepositSol(glamState, stakePool, amount, txOptions = {}) {
@@ -15593,45 +15668,13 @@ class MintClient {
15593
15668
  }
15594
15669
  }
15595
15670
 
15596
- // Kamino prod and staging use the same Farms program
15597
- const KaminoFarmsProgramId = new web3_js.PublicKey("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
15598
- const kLendProgramId = {
15599
- prod: new web3_js.PublicKey("KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"),
15600
- staging: new web3_js.PublicKey("SLendK7ySfcEzyaFqy93gDnD3RtrpXJcnRwb6zFHJSh")
15601
- };
15602
- // Kamino has multiple lending markets, use the main market for tests
15603
- const lendingMarketMain = {
15604
- prod: new web3_js.PublicKey("H6rHXmXoCQvq8Ue81MqNh7ow5ysPa1dSozwW3PU1dDH6"),
15605
- staging: new web3_js.PublicKey("6WVSwDQXrBZeQVnu6hpnsRZhodaJTZBUaC334SiiBKdb")
15606
- };
15607
- const solReserve = {
15608
- prod: new web3_js.PublicKey("6gTJfuPHEg6uRAijRkMqNc9kan4sVZejKMxmvx2grT1p"),
15609
- staging: new web3_js.PublicKey("EaAuYkMrA9rmnU9eVvHi63yqZzKzmnVj3PWFnmW9RD4W")
15671
+ const LOOKUP_TABLE = new web3_js.PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2");
15672
+ const DEFAULT_OBLIGATION_ARGS = {
15673
+ tag: 0,
15674
+ id: 0
15610
15675
  };
15611
- const lendingMarketAuthority = {
15612
- prod: new web3_js.PublicKey("Dx8iy2o46sK1DzWbEcznqSKeLbLVeu7otkibA3WohGAj"),
15613
- staging: new web3_js.PublicKey("4zzBjUgjuNUrGqt8Xrig7SDLqBPgZo3v3R7YEuBQoiC4")
15614
- };
15615
- const reserveFarmState = {
15616
- prod: new web3_js.PublicKey("BgMEUzcjkJxEH1PdPkZyv3NbUynwbkPiNJ7X2x7G1JmH"),
15617
- staging: new web3_js.PublicKey("CtGYmztwXGrDtUrRCEydrwkwpJ7ptAY5BkfzThkVPPK9")
15618
- };
15619
- const reserveLiquiditySupply = {
15620
- prod: new web3_js.PublicKey("ywaaLvG7t1vXJo8sT3UzE8yzzZtxLM7Fmev64Jbooye"),
15621
- staging: new web3_js.PublicKey("GaTJgVfgUTTYyZYTQB36rXTQEbv1i1LUvfGSBDAr2An1")
15622
- };
15623
- const reserveCollateralMint = {
15624
- prod: new web3_js.PublicKey("DxzDt5kPdFkMy9AANiZh4zuoitobqsn1G6bdoNyjePC2"),
15625
- staging: new web3_js.PublicKey("966sqybMQJfwYgiEDQqiFsSK5o9tFPyBptZ3GFXbF7vR")
15626
- };
15627
- const reserveDestinationDepositCollateral = {
15628
- prod: new web3_js.PublicKey("8qnXfbaLbY6Y4xiCP6SZ3RK8ccjVa8DhALzDGifBPeNx"),
15629
- staging: new web3_js.PublicKey("DZpgVJq3WpwRpPXNwzvLwVMerJodqCiitxAeU5QgkJe3")
15630
- };
15631
- const scopePrices = new web3_js.PublicKey("3NJYftD5sjVfxSnUdZ1wVML8f3aC6mp1CXCL6L7TnU8C");
15676
+ const SCOPE_PRICES = new web3_js.PublicKey("3NJYftD5sjVfxSnUdZ1wVML8f3aC6mp1CXCL6L7TnU8C");
15632
15677
  function refreshObligation(accounts, programId) {
15633
- // First time deposit we don't need additional accounts
15634
- // FIXME: but we need to append Kamino reserve accounts if the obligation uses them
15635
15678
  const keys = [
15636
15679
  {
15637
15680
  pubkey: accounts.lendingMarket,
@@ -15644,6 +15687,13 @@ function refreshObligation(accounts, programId) {
15644
15687
  isWritable: true
15645
15688
  }
15646
15689
  ];
15690
+ accounts.reserves.forEach((reserve)=>{
15691
+ keys.push({
15692
+ pubkey: reserve,
15693
+ isSigner: false,
15694
+ isWritable: false
15695
+ });
15696
+ });
15647
15697
  const identifier = Buffer.from([
15648
15698
  33,
15649
15699
  132,
@@ -15795,22 +15845,78 @@ function refreshObligationFarmsForReserve(args, accounts, programId) {
15795
15845
  return ix;
15796
15846
  }
15797
15847
  class KaminoLendingClient {
15798
- async initialize(statePda, txOptions = {}) {
15799
- const tx = await this.initializeTx(statePda, txOptions);
15848
+ /**
15849
+ * Initializes Kamino user metadata
15850
+ *
15851
+ * @param statePda
15852
+ * @param market Lending market
15853
+ * @param referrer Referrer user metadata
15854
+ * @param txOptions
15855
+ * @returns
15856
+ */ async initUserMetadata(statePda, referrer, txOptions = {}) {
15857
+ const tx = await this.initUserMetadataTx(new web3_js.PublicKey(statePda), referrer ? new web3_js.PublicKey(referrer) : web3_js.PublicKey.default, txOptions);
15858
+ return await this.base.sendAndConfirm(tx);
15859
+ }
15860
+ /**
15861
+ * Deposits asset to the lending market.
15862
+ *
15863
+ * @param statePda
15864
+ * @param market Lending market
15865
+ * @param asset Asset mint
15866
+ * @param amount Amount to deposit
15867
+ * @param txOptions
15868
+ * @returns
15869
+ */ async deposit(statePda, market, asset, amount, txOptions = {}) {
15870
+ const tx = await this.depositTx(new web3_js.PublicKey(statePda), new web3_js.PublicKey(market), new web3_js.PublicKey(asset), new anchor.BN(amount), txOptions);
15800
15871
  return await this.base.sendAndConfirm(tx);
15801
15872
  }
15802
- async deposit(statePda, amount, txOptions = {}) {
15803
- const tx = await this.depositTx(statePda, WSOL, amount, txOptions);
15873
+ /**
15874
+ * Withdraws asset from the lending market.
15875
+ *
15876
+ * @param statePda
15877
+ * @param market Lending market
15878
+ * @param asset Asset mint
15879
+ * @param amount Amount to deposit
15880
+ * @param txOptions
15881
+ * @returns
15882
+ */ async withdraw(statePda, market, asset, amount, txOptions = {}) {
15883
+ const tx = await this.withdrawTx(new web3_js.PublicKey(statePda), new web3_js.PublicKey(market), new web3_js.PublicKey(asset), new anchor.BN(amount), txOptions);
15884
+ return await this.base.sendAndConfirm(tx);
15885
+ }
15886
+ /**
15887
+ * Borrows asset from the lending market.
15888
+ *
15889
+ * @param statePda GLAM state
15890
+ * @param market Lending market
15891
+ * @param asset Asset mint
15892
+ * @param amount Amount to borrow
15893
+ * @param txOptions
15894
+ * @returns
15895
+ */ async borrow(statePda, market, asset, amount, txOptions = {}) {
15896
+ const tx = await this.borrowTx(new web3_js.PublicKey(statePda), new web3_js.PublicKey(market), new web3_js.PublicKey(asset), new anchor.BN(amount), txOptions);
15897
+ return await this.base.sendAndConfirm(tx);
15898
+ }
15899
+ /**
15900
+ * Repays asset to the lending market.
15901
+ *
15902
+ * @param statePda
15903
+ * @param market
15904
+ * @param asset
15905
+ * @param amount
15906
+ * @param txOptions
15907
+ * @returns
15908
+ */ async repay(statePda, market, asset, amount, txOptions = {}) {
15909
+ const tx = await this.repayTx(new web3_js.PublicKey(statePda), new web3_js.PublicKey(market), new web3_js.PublicKey(asset), new anchor.BN(amount), txOptions);
15804
15910
  return await this.base.sendAndConfirm(tx);
15805
15911
  }
15806
15912
  getUserMetadataPda(owner) {
15807
15913
  const [userMetadataPda] = web3_js.PublicKey.findProgramAddressSync([
15808
15914
  Buffer.from("user_meta"),
15809
15915
  owner.toBuffer()
15810
- ], kLendProgramId.prod);
15916
+ ], KAMINO_LENDING_PROGRAM);
15811
15917
  return userMetadataPda;
15812
15918
  }
15813
- getObligationPda(owner, args) {
15919
+ getObligationPda(owner, market, args = DEFAULT_OBLIGATION_ARGS) {
15814
15920
  const seed = [
15815
15921
  Buffer.from([
15816
15922
  args.tag
@@ -15819,141 +15925,627 @@ class KaminoLendingClient {
15819
15925
  args.id
15820
15926
  ]),
15821
15927
  owner.toBuffer(),
15822
- lendingMarketMain.prod.toBuffer(),
15928
+ market.toBuffer(),
15823
15929
  web3_js.PublicKey.default.toBuffer(),
15824
15930
  web3_js.PublicKey.default.toBuffer()
15825
15931
  ];
15826
- const [obligation, _] = web3_js.PublicKey.findProgramAddressSync(seed, kLendProgramId.prod);
15932
+ const [obligation, _] = web3_js.PublicKey.findProgramAddressSync(seed, KAMINO_LENDING_PROGRAM);
15827
15933
  return obligation;
15828
15934
  }
15829
- getObligationFarm(obligation) {
15935
+ getObligationFarmState(obligation, farm) {
15830
15936
  const [obligationFarm] = web3_js.PublicKey.findProgramAddressSync([
15831
15937
  Buffer.from("user"),
15832
- reserveFarmState.prod.toBuffer(),
15938
+ farm.toBuffer(),
15833
15939
  obligation.toBuffer()
15834
- ], KaminoFarmsProgramId);
15940
+ ], KAMINO_FARM_PROGRAM);
15835
15941
  return obligationFarm;
15836
15942
  }
15837
- async initializeTx(statePda, txOptions) {
15838
- const signer = txOptions.signer || this.base.getSigner();
15839
- const vault = await this.base.getVaultPda(statePda);
15943
+ async initUserMetadataTx(glamState, referrer, txOptions) {
15944
+ const glamSigner = txOptions.signer || this.base.getSigner();
15945
+ const vault = this.base.getVaultPda(glamState);
15840
15946
  const userMetadata = this.getUserMetadataPda(vault);
15841
- const args = {
15842
- tag: 0,
15843
- id: 0
15844
- };
15845
- const obligation = this.getObligationPda(vault, args);
15846
- const obligationFarm = this.getObligationFarm(obligation);
15947
+ const lookupTable = new web3_js.PublicKey(0); // FIXME: create lookup table
15948
+ const referrerUserMetadata = referrer.equals(web3_js.PublicKey.default) ? KAMINO_LENDING_PROGRAM : referrer;
15847
15949
  // @ts-ignore
15848
- const initObligationIx = await this.base.program.methods.kaminoLendingInitObligation(args).accounts({
15849
- glamState: statePda,
15850
- glamSigner: signer,
15851
- obligation,
15852
- lendingMarket: lendingMarketMain.prod,
15853
- seed1Account: new web3_js.PublicKey(0),
15854
- seed2Account: new web3_js.PublicKey(0),
15855
- ownerUserMetadata: userMetadata
15856
- }).instruction();
15857
- const initObligationFarmIx = await this.base.program.methods.kaminoLendingInitObligationFarmsForReserve(0).accounts({
15858
- glamState: statePda,
15859
- glamSigner: signer,
15860
- obligation,
15861
- lendingMarketAuthority: lendingMarketAuthority.prod,
15862
- reserve: solReserve.prod,
15863
- reserveFarmState: reserveFarmState.prod,
15864
- obligationFarm,
15865
- lendingMarket: lendingMarketMain.prod,
15866
- farmsProgram: KaminoFarmsProgramId
15867
- }).instruction();
15868
- const tx = await this.base.program.methods.kaminoLendingInitUserMetadata(new web3_js.PublicKey(0)).accounts({
15869
- glamState: statePda,
15870
- glamSigner: signer,
15950
+ const tx = await this.base.program.methods.kaminoLendingInitUserMetadata(lookupTable).accounts({
15951
+ glamState,
15952
+ glamSigner,
15871
15953
  userMetadata,
15872
- referrerUserMetadata: kLendProgramId.prod
15873
- }).postInstructions([
15874
- initObligationIx,
15875
- initObligationFarmIx
15876
- ]).transaction();
15954
+ referrerUserMetadata
15955
+ }).transaction();
15877
15956
  const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
15878
15957
  return vTx;
15879
15958
  }
15880
- async depositTx(statePda, asset, amount, txOptions) {
15881
- if (!asset.equals(WSOL)) {
15882
- throw new Error("Only WSOL is supported");
15959
+ refreshReserveIxs(lendingMarket, reserves) {
15960
+ return reserves.map((reserve)=>refreshReserve({
15961
+ reserve,
15962
+ lendingMarket,
15963
+ pythOracle: KAMINO_LENDING_PROGRAM,
15964
+ switchboardPriceOracle: KAMINO_LENDING_PROGRAM,
15965
+ switchboardTwapOracle: KAMINO_LENDING_PROGRAM,
15966
+ scopePrices: SCOPE_PRICES
15967
+ }, KAMINO_LENDING_PROGRAM));
15968
+ }
15969
+ refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves) {
15970
+ return parsedReserves.map((parsedReserve)=>{
15971
+ const { farmCollateral, farmDebt } = parsedReserve;
15972
+ return [
15973
+ farmCollateral,
15974
+ farmDebt
15975
+ ].filter((farm)=>!!farm).map((farm)=>{
15976
+ const obligationFarmUserState = this.getObligationFarmState(obligation, farm);
15977
+ return refreshObligationFarmsForReserve({
15978
+ mode: 0
15979
+ }, {
15980
+ crank: this.base.getSigner(),
15981
+ baseAccounts: {
15982
+ obligation,
15983
+ lendingMarketAuthority: this.getMarketAuthority(lendingMarket),
15984
+ reserve: parsedReserve.address,
15985
+ reserveFarmState: farm,
15986
+ obligationFarmUserState,
15987
+ lendingMarket
15988
+ },
15989
+ farmsProgram: KAMINO_FARM_PROGRAM,
15990
+ rent: web3_js.SYSVAR_RENT_PUBKEY,
15991
+ systemProgram: web3_js.SystemProgram.programId
15992
+ }, KAMINO_LENDING_PROGRAM);
15993
+ });
15994
+ }).flat();
15995
+ }
15996
+ /**
15997
+ * Returns an array of instructions for refreshing an existing obligation and reserves it depends on.
15998
+ */ async getRefreshIxs(obligation, lendingMarket) {
15999
+ // If obligation has deposits or borrows, we need the following refresh ixs:
16000
+ // - refreshReserve x N_reserves
16001
+ // - refreshObligation
16002
+ // - refreshObligationFarmsForReserve x M_farms
16003
+ const { deposits, borrows } = await this.fetchAndParseObligation(obligation);
16004
+ const reserves = deposits.concat(borrows).map((d)=>d.reserve);
16005
+ const parsedReserves = await this.fetchAndParseReserves(reserves);
16006
+ return [
16007
+ ...this.refreshReserveIxs(lendingMarket, reserves),
16008
+ refreshObligation({
16009
+ lendingMarket,
16010
+ obligation,
16011
+ reserves
16012
+ }, KAMINO_LENDING_PROGRAM),
16013
+ ...this.refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves)
16014
+ ];
16015
+ }
16016
+ getMarketAuthority(market) {
16017
+ const [authority, _] = web3_js.PublicKey.findProgramAddressSync([
16018
+ Buffer.from("lma"),
16019
+ market.toBuffer()
16020
+ ], KAMINO_LENDING_PROGRAM);
16021
+ return authority;
16022
+ }
16023
+ reservePdas(market, mint) {
16024
+ const [liquiditySupplyVault] = web3_js.PublicKey.findProgramAddressSync([
16025
+ Buffer.from("reserve_liq_supply"),
16026
+ market.toBuffer(),
16027
+ mint.toBuffer()
16028
+ ], KAMINO_LENDING_PROGRAM);
16029
+ const [collateralMint] = web3_js.PublicKey.findProgramAddressSync([
16030
+ Buffer.from("reserve_coll_mint"),
16031
+ market.toBuffer(),
16032
+ mint.toBuffer()
16033
+ ], KAMINO_LENDING_PROGRAM);
16034
+ const [collateralSupplyVault] = web3_js.PublicKey.findProgramAddressSync([
16035
+ Buffer.from("reserve_coll_supply"),
16036
+ market.toBuffer(),
16037
+ mint.toBuffer()
16038
+ ], KAMINO_LENDING_PROGRAM);
16039
+ const [feeVault] = web3_js.PublicKey.findProgramAddressSync([
16040
+ Buffer.from("fee_receiver"),
16041
+ market.toBuffer(),
16042
+ mint.toBuffer()
16043
+ ], KAMINO_LENDING_PROGRAM);
16044
+ return {
16045
+ liquiditySupplyVault,
16046
+ collateralMint,
16047
+ collateralSupplyVault,
16048
+ feeVault
16049
+ };
16050
+ }
16051
+ /**
16052
+ * Fetches and parses obligation account
16053
+ *
16054
+ * @param obligation User obligation pubkey
16055
+ * @returns Pubkeys of reserves for deposits and borrows
16056
+ */ async fetchAndParseObligation(obligation) {
16057
+ const cached = this.obligations.get(obligation);
16058
+ if (cached) {
16059
+ return cached;
15883
16060
  }
15884
- const signer = txOptions.signer || this.base.getSigner();
15885
- const vault = this.base.getVaultPda(statePda);
15886
- const args = {
15887
- tag: 0,
15888
- id: 0
16061
+ const obligationAccount = await this.base.provider.connection.getAccountInfo(obligation);
16062
+ if (!obligationAccount) {
16063
+ return {
16064
+ deposits: [],
16065
+ borrows: []
16066
+ };
16067
+ }
16068
+ const data = obligationAccount.data;
16069
+ // read deposits
16070
+ let depositsOffset = 96;
16071
+ let depositSize = 136;
16072
+ let numDeposits = 8;
16073
+ const depositsData = data.subarray(depositsOffset, depositsOffset + numDeposits * depositSize);
16074
+ const deposits = Array.from({
16075
+ length: numDeposits
16076
+ }, (_, i)=>{
16077
+ const depositData = depositsData.subarray(i * depositSize, (i + 1) * depositSize);
16078
+ return {
16079
+ reserve: new web3_js.PublicKey(depositData.subarray(0, 32))
16080
+ };
16081
+ }).filter((d)=>!d.reserve.equals(web3_js.PublicKey.default));
16082
+ // read borrows
16083
+ let borrowsOffset = 1208;
16084
+ let borrowSize = 200;
16085
+ let numBorrows = 5;
16086
+ const borrowsData = data.subarray(borrowsOffset, borrowsOffset + numBorrows * borrowSize);
16087
+ const borrows = Array.from({
16088
+ length: numBorrows
16089
+ }, (_, i)=>{
16090
+ const borrowData = borrowsData.subarray(i * borrowSize, (i + 1) * borrowSize);
16091
+ return {
16092
+ reserve: new web3_js.PublicKey(borrowData.subarray(0, 32))
16093
+ };
16094
+ }).filter((d)=>!d.reserve.equals(web3_js.PublicKey.default));
16095
+ const parsedObligation = {
16096
+ deposits,
16097
+ borrows
15889
16098
  };
15890
- const obligation = this.getObligationPda(vault, args);
15891
- const obligationFarm = this.getObligationFarm(obligation);
15892
- const refreshIxs = [
15893
- refreshReserve({
15894
- reserve: solReserve.prod,
15895
- lendingMarket: lendingMarketMain.prod,
15896
- pythOracle: kLendProgramId.prod,
15897
- switchboardPriceOracle: kLendProgramId.prod,
15898
- switchboardTwapOracle: kLendProgramId.prod,
15899
- scopePrices
15900
- }, kLendProgramId.prod),
15901
- refreshObligation({
15902
- lendingMarket: lendingMarketMain.prod,
15903
- obligation
15904
- }, kLendProgramId.prod),
15905
- refreshObligationFarmsForReserve({
15906
- mode: 0
15907
- }, {
15908
- crank: this.base.getSigner(),
15909
- baseAccounts: {
16099
+ this.obligations.set(obligation, parsedObligation);
16100
+ return parsedObligation;
16101
+ }
16102
+ /**
16103
+ * We only need pubkeys that don't change over time. No need to fetch them every time.
16104
+ *
16105
+ * @param market
16106
+ * @param asset
16107
+ * @returns
16108
+ */ async fetchAndParseReserves(reserves) {
16109
+ if (this.pubkeyArraysEqual(reserves, Array.from(this.reserves.keys()))) {
16110
+ return Array.from(this.reserves.values());
16111
+ }
16112
+ const reserveAccounts = await this.base.provider.connection.getMultipleAccountsInfo(reserves);
16113
+ if (reserveAccounts.find((a)=>!a)) {
16114
+ throw new Error("Not all reserves can be found");
16115
+ }
16116
+ return reserveAccounts.filter((a)=>!!a).map((account, i)=>{
16117
+ const data = account.data;
16118
+ const market = new web3_js.PublicKey(data.subarray(32, 64));
16119
+ const farmCollateral = new web3_js.PublicKey(data.subarray(64, 96));
16120
+ const farmDebt = new web3_js.PublicKey(data.subarray(96, 128));
16121
+ const liquidityMint = new web3_js.PublicKey(data.subarray(128, 160));
16122
+ const parsed = {
16123
+ address: reserves[i],
16124
+ farmCollateral: farmCollateral.equals(web3_js.PublicKey.default) ? undefined : farmCollateral,
16125
+ farmDebt: farmDebt.equals(web3_js.PublicKey.default) ? undefined : farmDebt,
16126
+ liquidityMint,
16127
+ ...this.reservePdas(market, liquidityMint)
16128
+ };
16129
+ this.reserves.set(reserves[i], parsed);
16130
+ return parsed;
16131
+ });
16132
+ }
16133
+ async findAndParseReserve(market, asset) {
16134
+ const accounts = await this.base.provider.connection.getProgramAccounts(KAMINO_LENDING_PROGRAM, {
16135
+ filters: [
16136
+ {
16137
+ dataSize: 8624
16138
+ },
16139
+ {
16140
+ memcmp: {
16141
+ offset: 32,
16142
+ bytes: market.toBase58()
16143
+ }
16144
+ },
16145
+ {
16146
+ memcmp: {
16147
+ offset: 128,
16148
+ bytes: asset.toBase58()
16149
+ }
16150
+ }
16151
+ ]
16152
+ });
16153
+ if (accounts.length === 0) {
16154
+ throw new Error("Reserve not found");
16155
+ }
16156
+ const account = accounts[0];
16157
+ const data = account.account.data;
16158
+ const farmCollateral = new web3_js.PublicKey(data.subarray(64, 96));
16159
+ const farmDebt = new web3_js.PublicKey(data.subarray(96, 128));
16160
+ const parsed = {
16161
+ address: account.pubkey,
16162
+ farmCollateral: farmCollateral.equals(web3_js.PublicKey.default) ? undefined : farmCollateral,
16163
+ farmDebt: farmDebt.equals(web3_js.PublicKey.default) ? undefined : farmDebt,
16164
+ liquidityMint: asset,
16165
+ ...this.reservePdas(market, asset)
16166
+ };
16167
+ this.reserves.set(account.pubkey, parsed);
16168
+ return parsed;
16169
+ }
16170
+ async depositTx(glamState, market, asset, amount, txOptions) {
16171
+ const glamSigner = txOptions.signer || this.base.getSigner();
16172
+ const vault = this.base.getVaultPda(glamState);
16173
+ const userMetadata = this.getUserMetadataPda(vault);
16174
+ const preInstructions = [];
16175
+ const postInstructions = [];
16176
+ const depositReserve = await this.findAndParseReserve(market, asset);
16177
+ const obligation = this.getObligationPda(vault, market, DEFAULT_OBLIGATION_ARGS);
16178
+ // If obligation doesn't exist, initialize & refresh obligation and collateral farm state first
16179
+ const obligationAccount = await this.base.provider.connection.getAccountInfo(obligation);
16180
+ if (!obligationAccount) {
16181
+ preInstructions.push(await this.base.program.methods.kaminoLendingInitObligation(DEFAULT_OBLIGATION_ARGS).accounts({
16182
+ glamState,
16183
+ glamSigner,
16184
+ obligation,
16185
+ lendingMarket: market,
16186
+ seed1Account: new web3_js.PublicKey(0),
16187
+ seed2Account: new web3_js.PublicKey(0),
16188
+ ownerUserMetadata: userMetadata
16189
+ }).instruction());
16190
+ }
16191
+ // If reserve has collateral farm but obligation farm state doesn't exist, initialize it
16192
+ let obligationFarm = null;
16193
+ if (depositReserve.farmCollateral) {
16194
+ obligationFarm = this.getObligationFarmState(obligation, depositReserve.farmCollateral);
16195
+ const obligationFarmAccount = await this.base.provider.connection.getAccountInfo(obligationFarm);
16196
+ if (!obligationFarmAccount) {
16197
+ preInstructions.push(await this.base.program.methods.kaminoLendingInitObligationFarmsForReserve(0) // TODO: What does mode do?
16198
+ .accounts({
16199
+ glamState,
16200
+ glamSigner,
15910
16201
  obligation,
15911
- lendingMarketAuthority: lendingMarketAuthority.prod,
15912
- reserve: solReserve.prod,
15913
- reserveFarmState: reserveFarmState.prod,
15914
- obligationFarmUserState: obligationFarm,
15915
- lendingMarket: lendingMarketMain.prod
15916
- },
15917
- farmsProgram: KaminoFarmsProgramId,
15918
- rent: web3_js.SYSVAR_RENT_PUBKEY,
15919
- systemProgram: web3_js.SystemProgram.programId
15920
- }, kLendProgramId.prod)
15921
- ];
15922
- const tx = await this.base.program.methods.kaminoLendingDepositReserveLiquidityAndObligationCollateralV2(new anchor.BN(amount)).accounts({
15923
- glamState: statePda,
15924
- glamSigner: signer,
16202
+ lendingMarketAuthority: this.getMarketAuthority(market),
16203
+ reserve: depositReserve.address,
16204
+ reserveFarmState: depositReserve.farmCollateral,
16205
+ obligationFarm,
16206
+ lendingMarket: market,
16207
+ farmsProgram: KAMINO_FARM_PROGRAM
16208
+ }).instruction());
16209
+ }
16210
+ }
16211
+ const reservesToRefresh = [];
16212
+ const { deposits, borrows } = await this.fetchAndParseObligation(obligation);
16213
+ const reservesInUse = deposits.concat(borrows).map((d)=>d.reserve);
16214
+ if (reservesInUse.find((r)=>r.equals(depositReserve.address))) {
16215
+ reservesToRefresh.push(...reservesInUse);
16216
+ } else {
16217
+ reservesToRefresh.push(depositReserve.address, ...reservesInUse);
16218
+ }
16219
+ // Refresh reserves, including deposit reserve and reserves in use
16220
+ preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
16221
+ // Refresh obligation with reserves in use
16222
+ preInstructions.push(refreshObligation({
16223
+ lendingMarket: market,
15925
16224
  obligation,
15926
- lendingMarket: lendingMarketMain.prod,
15927
- lendingMarketAuthority: lendingMarketAuthority.prod,
15928
- reserve: solReserve.prod,
16225
+ reserves: reservesInUse
16226
+ }, KAMINO_LENDING_PROGRAM));
16227
+ if (depositReserve.farmCollateral) {
16228
+ const ixs = this.refreshObligationFarmsForReserveIxs(obligation, market, [
16229
+ depositReserve
16230
+ ]);
16231
+ preInstructions.push(...ixs);
16232
+ postInstructions.push(...ixs); // farms must be refreshed after deposit
16233
+ }
16234
+ // If deposit asset is WSOL, wrap SOL first in case vault doesn't have enough wSOL
16235
+ const userSourceLiquidity = this.base.getVaultAta(glamState, asset);
16236
+ if (asset.equals(WSOL)) {
16237
+ const wrapSolIxs = await this.base.maybeWrapSol(glamState, amount);
16238
+ preInstructions.unshift(...wrapSolIxs);
16239
+ // Close wSOL ata automatically after deposit
16240
+ if (wrapSolIxs.length > 0) {
16241
+ const closeIx = await this.base.program.methods.tokenCloseAccount().accounts({
16242
+ glamState,
16243
+ glamSigner,
16244
+ tokenAccount: userSourceLiquidity,
16245
+ cpiProgram: splToken.TOKEN_PROGRAM_ID
16246
+ }).instruction();
16247
+ postInstructions.push(closeIx);
16248
+ }
16249
+ }
16250
+ // @ts-ignore
16251
+ const tx = await this.base.program.methods.kaminoLendingDepositReserveLiquidityAndObligationCollateralV2(amount).accounts({
16252
+ glamState,
16253
+ glamSigner,
16254
+ obligation,
16255
+ lendingMarket: market,
16256
+ lendingMarketAuthority: this.getMarketAuthority(market),
16257
+ reserve: depositReserve.address,
15929
16258
  reserveLiquidityMint: asset,
15930
- reserveLiquiditySupply: reserveLiquiditySupply.prod,
15931
- reserveCollateralMint: reserveCollateralMint.prod,
15932
- reserveDestinationDepositCollateral: reserveDestinationDepositCollateral.prod,
15933
- userSourceLiquidity: this.base.getVaultAta(statePda, asset),
15934
- placeholderUserDestinationCollateral: kLendProgramId.prod,
16259
+ reserveLiquiditySupply: depositReserve.liquiditySupplyVault,
16260
+ reserveCollateralMint: depositReserve.collateralMint,
16261
+ reserveDestinationDepositCollateral: depositReserve.collateralSupplyVault,
16262
+ userSourceLiquidity,
16263
+ placeholderUserDestinationCollateral: KAMINO_LENDING_PROGRAM,
15935
16264
  collateralTokenProgram: splToken.TOKEN_PROGRAM_ID,
15936
16265
  liquidityTokenProgram: splToken.TOKEN_PROGRAM_ID,
15937
16266
  instructionSysvarAccount: web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,
15938
16267
  obligationFarmUserState: obligationFarm,
15939
- reserveFarmState: reserveFarmState.prod,
15940
- farmsProgram: KaminoFarmsProgramId
15941
- }).preInstructions(refreshIxs) // 3 refresh ixs
15942
- .postInstructions([
15943
- refreshIxs[2]
15944
- ]) // 1 refresh ix
15945
- .transaction();
15946
- const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
16268
+ // @ts-ignore
16269
+ reserveFarmState: depositReserve.farmCollateral,
16270
+ farmsProgram: KAMINO_FARM_PROGRAM
16271
+ }).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
16272
+ const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
16273
+ LOOKUP_TABLE
16274
+ ]);
16275
+ const vTx = await this.base.intoVersionedTransaction(tx, {
16276
+ ...txOptions,
16277
+ lookupTables
16278
+ });
16279
+ return vTx;
16280
+ }
16281
+ async withdrawTx(glamState, market, asset, amount, txOptions) {
16282
+ const glamSigner = txOptions.signer || this.base.getSigner();
16283
+ const vault = this.base.getVaultPda(glamState);
16284
+ const preInstructions = [];
16285
+ const postInstructions = [];
16286
+ const withdrawReserve = await this.findAndParseReserve(market, asset);
16287
+ const obligation = this.getObligationPda(vault, market, DEFAULT_OBLIGATION_ARGS);
16288
+ let obligationFarm = null;
16289
+ // If reserve has debt farm but obligation farm state doesn't exist, initialize it
16290
+ if (withdrawReserve.farmCollateral) {
16291
+ obligationFarm = this.getObligationFarmState(obligation, withdrawReserve.farmCollateral);
16292
+ const obligationFarmAccount = await this.base.provider.connection.getAccountInfo(obligationFarm);
16293
+ if (!obligationFarmAccount) {
16294
+ preInstructions.push(await this.base.program.methods.kaminoLendingInitObligationFarmsForReserve(0) // TODO: What does mode do?
16295
+ .accounts({
16296
+ glamState,
16297
+ glamSigner,
16298
+ obligation,
16299
+ lendingMarketAuthority: this.getMarketAuthority(market),
16300
+ reserve: withdrawReserve.address,
16301
+ reserveFarmState: withdrawReserve.farmCollateral,
16302
+ obligationFarm,
16303
+ lendingMarket: market,
16304
+ farmsProgram: KAMINO_FARM_PROGRAM
16305
+ }).instruction());
16306
+ }
16307
+ }
16308
+ const reservesToRefresh = [];
16309
+ const { deposits, borrows } = await this.fetchAndParseObligation(obligation);
16310
+ const reservesInUse = deposits.concat(borrows).map((d)=>d.reserve);
16311
+ if (reservesInUse.find((r)=>r.equals(withdrawReserve.address))) {
16312
+ reservesToRefresh.push(...reservesInUse);
16313
+ } else {
16314
+ reservesToRefresh.push(withdrawReserve.address, ...reservesInUse);
16315
+ }
16316
+ // Refresh reserves, including deposit reserve and reserves in use
16317
+ preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
16318
+ // Refresh obligation with reserves in use
16319
+ preInstructions.push(refreshObligation({
16320
+ lendingMarket: market,
16321
+ obligation,
16322
+ reserves: reservesInUse
16323
+ }, KAMINO_LENDING_PROGRAM));
16324
+ if (withdrawReserve.farmCollateral) {
16325
+ const ixs = this.refreshObligationFarmsForReserveIxs(obligation, market, [
16326
+ withdrawReserve
16327
+ ]);
16328
+ preInstructions.push(...ixs);
16329
+ postInstructions.push(...ixs); // farms must be refreshed after withdraw
16330
+ }
16331
+ // Create asset ATA in case it doesn't exist. Add it to the beginning of preInstructions
16332
+ const userDestinationLiquidity = this.base.getVaultAta(glamState, asset);
16333
+ const createAtaIx = splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, userDestinationLiquidity, vault, asset);
16334
+ preInstructions.unshift(createAtaIx);
16335
+ const withdrawIx = await this.base.program.methods.kaminoLendingWithdrawObligationCollateralAndRedeemReserveCollateralV2(amount).accounts({
16336
+ glamState,
16337
+ glamSigner,
16338
+ obligation,
16339
+ lendingMarket: market,
16340
+ lendingMarketAuthority: this.getMarketAuthority(market),
16341
+ withdrawReserve: withdrawReserve.address,
16342
+ reserveLiquidityMint: asset,
16343
+ reserveSourceCollateral: withdrawReserve.collateralSupplyVault,
16344
+ reserveCollateralMint: withdrawReserve.collateralMint,
16345
+ reserveLiquiditySupply: withdrawReserve.liquiditySupplyVault,
16346
+ userDestinationLiquidity: this.base.getVaultAta(glamState, asset),
16347
+ placeholderUserDestinationCollateral: null,
16348
+ collateralTokenProgram: splToken.TOKEN_PROGRAM_ID,
16349
+ liquidityTokenProgram: splToken.TOKEN_PROGRAM_ID,
16350
+ instructionSysvarAccount: web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,
16351
+ obligationFarmUserState: obligationFarm,
16352
+ // @ts-ignore
16353
+ reserveFarmState: withdrawReserve.farmCollateral,
16354
+ farmsProgram: KAMINO_FARM_PROGRAM
16355
+ }).instruction();
16356
+ // The final instructions in the tx:
16357
+ // - refreshReserve * N
16358
+ // - refreshObligation
16359
+ // - refreshObligationFarmsForReserve (if farm exists)
16360
+ // - withdrawIx
16361
+ // - refreshObligationFarmsForReserve (if farm exists)
16362
+ const tx = new web3_js.Transaction();
16363
+ tx.add(...preInstructions, withdrawIx, ...postInstructions);
16364
+ const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
16365
+ LOOKUP_TABLE
16366
+ ]);
16367
+ const vTx = await this.base.intoVersionedTransaction(tx, {
16368
+ ...txOptions,
16369
+ lookupTables
16370
+ });
16371
+ return vTx;
16372
+ }
16373
+ async borrowTx(glamState, market, asset, amount, txOptions) {
16374
+ const glamSigner = txOptions.signer || this.base.getSigner();
16375
+ const vault = this.base.getVaultPda(glamState);
16376
+ const preInstructions = [];
16377
+ const borrowReserve = await this.findAndParseReserve(market, asset);
16378
+ const obligation = this.getObligationPda(vault, market, DEFAULT_OBLIGATION_ARGS);
16379
+ let obligationFarm = null;
16380
+ // If reserve has debt farm but obligation farm state doesn't exist, initialize it
16381
+ if (borrowReserve.farmDebt) {
16382
+ obligationFarm = this.getObligationFarmState(obligation, borrowReserve.farmDebt);
16383
+ const obligationFarmAccount = await this.base.provider.connection.getAccountInfo(obligationFarm);
16384
+ if (!obligationFarmAccount) {
16385
+ preInstructions.push(await this.base.program.methods.kaminoLendingInitObligationFarmsForReserve(0) // TODO: What does mode do?
16386
+ .accounts({
16387
+ glamState,
16388
+ glamSigner,
16389
+ obligation,
16390
+ lendingMarketAuthority: this.getMarketAuthority(market),
16391
+ reserve: borrowReserve.address,
16392
+ reserveFarmState: borrowReserve.farmDebt,
16393
+ obligationFarm,
16394
+ lendingMarket: market,
16395
+ farmsProgram: KAMINO_FARM_PROGRAM
16396
+ }).instruction());
16397
+ }
16398
+ }
16399
+ const reservesToRefresh = [];
16400
+ const { deposits, borrows } = await this.fetchAndParseObligation(obligation);
16401
+ const reservesInUse = deposits.concat(borrows).map((d)=>d.reserve);
16402
+ if (reservesInUse.find((r)=>r.equals(borrowReserve.address))) {
16403
+ reservesToRefresh.push(...reservesInUse);
16404
+ } else {
16405
+ reservesToRefresh.push(borrowReserve.address, ...reservesInUse);
16406
+ }
16407
+ // Refresh reserves, including deposit reserve and reserves in use
16408
+ preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
16409
+ // Refresh obligation with reserves in use
16410
+ preInstructions.push(refreshObligation({
16411
+ lendingMarket: market,
16412
+ obligation,
16413
+ reserves: reservesInUse
16414
+ }, KAMINO_LENDING_PROGRAM));
16415
+ // Don't need to refresh debt farm for borrow
16416
+ /*
16417
+ if (borrowReserve.farmDebt) {
16418
+ const ixs = this.refreshObligationFarmsForReserveIxs(obligation, market, [
16419
+ borrowReserve,
16420
+ ]);
16421
+ preInstructions.push(...ixs);
16422
+ postInstructions.push(...ixs); // farms must be refreshed after deposit
16423
+ }
16424
+ */ // Create asset ATA in case it doesn't exist. Add it to the beginning of preInstructions
16425
+ const userDestinationLiquidity = this.base.getVaultAta(glamState, asset);
16426
+ const createAtaIx = splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, userDestinationLiquidity, vault, asset);
16427
+ preInstructions.unshift(createAtaIx);
16428
+ const borrowIx = await this.base.program.methods.kaminoLendingBorrowObligationLiquidityV2(amount).accounts({
16429
+ glamState,
16430
+ glamSigner,
16431
+ obligation,
16432
+ lendingMarket: market,
16433
+ lendingMarketAuthority: this.getMarketAuthority(market),
16434
+ borrowReserve: borrowReserve.address,
16435
+ borrowReserveLiquidityMint: asset,
16436
+ reserveSourceLiquidity: borrowReserve.liquiditySupplyVault,
16437
+ borrowReserveLiquidityFeeReceiver: borrowReserve.feeVault,
16438
+ userDestinationLiquidity: this.base.getVaultAta(glamState, asset),
16439
+ referrerTokenState: null,
16440
+ instructionSysvarAccount: web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,
16441
+ tokenProgram: splToken.TOKEN_PROGRAM_ID,
16442
+ obligationFarmUserState: obligationFarm,
16443
+ // @ts-ignore
16444
+ reserveFarmState: borrowReserve.farmDebt,
16445
+ farmsProgram: KAMINO_FARM_PROGRAM
16446
+ }).instruction();
16447
+ // The final instructions in the tx:
16448
+ // - refreshReserve * N
16449
+ // - refreshObligation
16450
+ // - borrowObligationLiquidityV2
16451
+ const tx = new web3_js.Transaction();
16452
+ tx.add(...preInstructions, borrowIx);
16453
+ const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
16454
+ LOOKUP_TABLE
16455
+ ]);
16456
+ const vTx = await this.base.intoVersionedTransaction(tx, {
16457
+ ...txOptions,
16458
+ lookupTables
16459
+ });
16460
+ return vTx;
16461
+ }
16462
+ async repayTx(glamState, market, asset, amount, txOptions = {}) {
16463
+ const glamSigner = txOptions.signer || this.base.getSigner();
16464
+ const vault = this.base.getVaultPda(glamState);
16465
+ const preInstructions = [];
16466
+ const repayReserve = await this.findAndParseReserve(market, asset);
16467
+ const obligation = this.getObligationPda(vault, market, DEFAULT_OBLIGATION_ARGS);
16468
+ let obligationFarm = null;
16469
+ // If reserve has debt farm but obligation farm state doesn't exist, initialize it
16470
+ if (repayReserve.farmDebt) {
16471
+ obligationFarm = this.getObligationFarmState(obligation, repayReserve.farmDebt);
16472
+ const obligationFarmAccount = await this.base.provider.connection.getAccountInfo(obligationFarm);
16473
+ if (!obligationFarmAccount) {
16474
+ preInstructions.push(await this.base.program.methods.kaminoLendingInitObligationFarmsForReserve(0) // TODO: What does mode do?
16475
+ .accounts({
16476
+ glamState,
16477
+ glamSigner,
16478
+ obligation,
16479
+ lendingMarketAuthority: this.getMarketAuthority(market),
16480
+ reserve: repayReserve.address,
16481
+ reserveFarmState: repayReserve.farmDebt,
16482
+ obligationFarm,
16483
+ lendingMarket: market,
16484
+ farmsProgram: KAMINO_FARM_PROGRAM
16485
+ }).instruction());
16486
+ }
16487
+ }
16488
+ const reservesToRefresh = [];
16489
+ const { deposits, borrows } = await this.fetchAndParseObligation(obligation);
16490
+ const reservesInUse = deposits.concat(borrows).map((d)=>d.reserve);
16491
+ if (reservesInUse.find((r)=>r.equals(repayReserve.address))) {
16492
+ reservesToRefresh.push(...reservesInUse);
16493
+ } else {
16494
+ reservesToRefresh.push(repayReserve.address, ...reservesInUse);
16495
+ }
16496
+ // Refresh reserves, including deposit reserve and reserves in use
16497
+ preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
16498
+ // Refresh obligation with reserves in use
16499
+ preInstructions.push(refreshObligation({
16500
+ lendingMarket: market,
16501
+ obligation,
16502
+ reserves: reservesInUse
16503
+ }, KAMINO_LENDING_PROGRAM));
16504
+ const repayIx = await this.base.program.methods.kaminoLendingRepayObligationLiquidityV2(amount).accounts({
16505
+ glamState,
16506
+ glamSigner,
16507
+ obligation,
16508
+ lendingMarket: market,
16509
+ lendingMarketAuthority: this.getMarketAuthority(market),
16510
+ repayReserve: repayReserve.address,
16511
+ reserveLiquidityMint: asset,
16512
+ reserveDestinationLiquidity: repayReserve.liquiditySupplyVault,
16513
+ userSourceLiquidity: this.base.getVaultAta(glamState, asset),
16514
+ instructionSysvarAccount: web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,
16515
+ tokenProgram: splToken.TOKEN_PROGRAM_ID,
16516
+ obligationFarmUserState: obligationFarm,
16517
+ // @ts-ignore
16518
+ reserveFarmState: repayReserve.farmDebt,
16519
+ farmsProgram: KAMINO_FARM_PROGRAM
16520
+ }).instruction();
16521
+ // The final instructions in the tx:
16522
+ // - refreshReserve * N
16523
+ // - refreshObligation
16524
+ // - repayObligationLiquidityV2
16525
+ const tx = new web3_js.Transaction();
16526
+ tx.add(...preInstructions, repayIx);
16527
+ const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
16528
+ LOOKUP_TABLE
16529
+ ]);
16530
+ const vTx = await this.base.intoVersionedTransaction(tx, {
16531
+ ...txOptions,
16532
+ lookupTables
16533
+ });
15947
16534
  return vTx;
15948
16535
  }
15949
16536
  constructor(base){
15950
16537
  this.base = base;
16538
+ this.reserves = new Map();
16539
+ this.obligations = new Map();
16540
+ this.pubkeyArraysEqual = (a, b)=>{
16541
+ if (a.length !== b.length) return false;
16542
+ a.sort();
16543
+ b.sort();
16544
+ return a.every((p, i)=>p.equals(b[i]));
16545
+ };
15951
16546
  }
15952
16547
  }
15953
16548
 
15954
- const METEORA_DLMM = new web3_js.PublicKey("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo");
15955
- const MEMO_PROGRAM_ID = new web3_js.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
15956
- new web3_js.PublicKey("5rCf1DM8LjKTw4YqhnoLcngyZYeNnQqztScTogYHAS6");
15957
16549
  // Pubkey::find_program_address(&[b"__event_authority"], &dlmm_interface::ID)
15958
16550
  const EVENT_AUTHORITY = new web3_js.PublicKey("D1ZN9Wj1fRSUQfCjhvnu1hqDMT7hzjzBBpi12nVniYD6");
15959
16551
  const DEFAULT_RANGE_INTERVAL = 34; // 34 bins on each side of the active bin, 69 bins in total
@@ -15982,7 +16574,7 @@ class MeteoraDlmmClient {
15982
16574
  lbPair: new web3_js.PublicKey(pool),
15983
16575
  position: position.publicKey,
15984
16576
  eventAuthority: EVENT_AUTHORITY,
15985
- program: METEORA_DLMM
16577
+ program: METEORA_DLMM_PROGRAM
15986
16578
  }).transaction();
15987
16579
  const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
15988
16580
  return await this.base.sendAndConfirm(vTx, [
@@ -16003,14 +16595,14 @@ class MeteoraDlmmClient {
16003
16595
  lbPair: new web3_js.PublicKey(pool),
16004
16596
  position,
16005
16597
  eventAuthority: EVENT_AUTHORITY,
16006
- program: METEORA_DLMM
16598
+ program: METEORA_DLMM_PROGRAM
16007
16599
  }).transaction();
16008
16600
  const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
16009
16601
  return await this.base.sendAndConfirm(vTx);
16010
16602
  }
16011
16603
  async addLiquidityByStrategy(statePda, position, amountX, amountY, strategyType, txOptions = {}) {
16012
16604
  const glamSigner = txOptions.signer || this.base.getSigner();
16013
- const { lbPair, lowerBinId, upperBinId, binArrayLower, binArrayUpper } = await this.parsePosition(new web3_js.PublicKey(position));
16605
+ const { lbPair, lowerBinId, upperBinId, binArrayLower, binArrayUpper } = await parseMeteoraPosition(this.base.provider.connection, new web3_js.PublicKey(position));
16014
16606
  const dlmmPool = await this.getDlmmPool(lbPair);
16015
16607
  const activeBinId = (await dlmmPool.getActiveBin()).binId;
16016
16608
  const glamState = new web3_js.PublicKey(statePda);
@@ -16048,7 +16640,7 @@ class MeteoraDlmmClient {
16048
16640
  glamState,
16049
16641
  position: new web3_js.PublicKey(position),
16050
16642
  lbPair,
16051
- binArrayBitmapExtension: dlmmPool.binArrayBitmapExtension ? dlmmPool.binArrayBitmapExtension.publicKey : METEORA_DLMM,
16643
+ binArrayBitmapExtension: dlmmPool.binArrayBitmapExtension ? dlmmPool.binArrayBitmapExtension.publicKey : METEORA_DLMM_PROGRAM,
16052
16644
  userTokenX: vaultTokenXAta,
16053
16645
  userTokenY: vaultTokenYAta,
16054
16646
  reserveX: dlmmPool.tokenX.reserve,
@@ -16058,13 +16650,13 @@ class MeteoraDlmmClient {
16058
16650
  tokenXProgram: splToken.TOKEN_PROGRAM_ID,
16059
16651
  tokenYProgram: splToken.TOKEN_PROGRAM_ID,
16060
16652
  eventAuthority: EVENT_AUTHORITY,
16061
- program: METEORA_DLMM
16653
+ program: METEORA_DLMM_PROGRAM
16062
16654
  }).preInstructions(preInstructions).remainingAccounts(remainingAccounts).transaction();
16063
16655
  const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
16064
16656
  return this.base.sendAndConfirm(vTx);
16065
16657
  }
16066
16658
  async removeLiquidityByRange(statePda, position, bpsToRemove, txOptions = {}) {
16067
- const { lbPair, lowerBinId, upperBinId, binArrayLower, binArrayUpper } = await this.parsePosition(new web3_js.PublicKey(position));
16659
+ const { lbPair, lowerBinId, upperBinId, binArrayLower, binArrayUpper } = await parseMeteoraPosition(this.base.provider.connection, new web3_js.PublicKey(position));
16068
16660
  const dlmmPool = await this.getDlmmPool(lbPair);
16069
16661
  const glamState = new web3_js.PublicKey(statePda);
16070
16662
  const vaultTokenXAta = this.base.getVaultAta(glamState, dlmmPool.tokenX.publicKey);
@@ -16077,13 +16669,14 @@ class MeteoraDlmmClient {
16077
16669
  isSigner: false,
16078
16670
  isWritable: true
16079
16671
  }));
16672
+ // @ts-ignore
16080
16673
  const tx = await this.base.program.methods.meteoraDlmmRemoveLiquidityByRange2(lowerBinId, upperBinId, bpsToRemove, {
16081
16674
  slices: []
16082
16675
  }).accounts({
16083
16676
  glamState,
16084
16677
  position: new web3_js.PublicKey(position),
16085
16678
  lbPair,
16086
- binArrayBitmapExtension: dlmmPool.binArrayBitmapExtension ? dlmmPool.binArrayBitmapExtension.publicKey : METEORA_DLMM,
16679
+ binArrayBitmapExtension: dlmmPool.binArrayBitmapExtension ? dlmmPool.binArrayBitmapExtension.publicKey : METEORA_DLMM_PROGRAM,
16087
16680
  userTokenX: vaultTokenXAta,
16088
16681
  userTokenY: vaultTokenYAta,
16089
16682
  reserveX: dlmmPool.tokenX.reserve,
@@ -16093,14 +16686,14 @@ class MeteoraDlmmClient {
16093
16686
  tokenXProgram: splToken.TOKEN_PROGRAM_ID,
16094
16687
  tokenYProgram: splToken.TOKEN_PROGRAM_ID,
16095
16688
  eventAuthority: EVENT_AUTHORITY,
16096
- memoProgram: MEMO_PROGRAM_ID,
16097
- program: METEORA_DLMM
16689
+ memoProgram: MEMO_PROGRAM,
16690
+ program: METEORA_DLMM_PROGRAM
16098
16691
  }).remainingAccounts(remainingAccounts).transaction();
16099
16692
  const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
16100
16693
  return this.base.sendAndConfirm(vTx);
16101
16694
  }
16102
16695
  async claimFee(statePda, position, txOptions = {}) {
16103
- const { lbPair, lowerBinId, upperBinId, binArrayLower, binArrayUpper } = await this.parsePosition(new web3_js.PublicKey(position));
16696
+ const { lbPair, lowerBinId, upperBinId, binArrayLower, binArrayUpper } = await parseMeteoraPosition(this.base.provider.connection, new web3_js.PublicKey(position));
16104
16697
  const dlmmPool = await this.getDlmmPool(lbPair);
16105
16698
  const glamState = new web3_js.PublicKey(statePda);
16106
16699
  const vaultTokenXAta = this.base.getVaultAta(glamState, dlmmPool.tokenX.publicKey);
@@ -16113,6 +16706,7 @@ class MeteoraDlmmClient {
16113
16706
  isSigner: false,
16114
16707
  isWritable: true
16115
16708
  }));
16709
+ // @ts-ignore
16116
16710
  const tx = await this.base.program.methods.meteoraDlmmClaimFee2(lowerBinId, upperBinId, {
16117
16711
  slices: []
16118
16712
  }).accounts({
@@ -16127,17 +16721,18 @@ class MeteoraDlmmClient {
16127
16721
  tokenYMint: dlmmPool.tokenY.publicKey,
16128
16722
  tokenProgramX: splToken.TOKEN_PROGRAM_ID,
16129
16723
  tokenProgramY: splToken.TOKEN_PROGRAM_ID,
16130
- memoProgram: MEMO_PROGRAM_ID,
16724
+ memoProgram: MEMO_PROGRAM,
16131
16725
  eventAuthority: EVENT_AUTHORITY,
16132
- program: METEORA_DLMM
16726
+ program: METEORA_DLMM_PROGRAM
16133
16727
  }).remainingAccounts(remainingAccounts).transaction();
16134
16728
  const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
16135
16729
  return await this.base.sendAndConfirm(vTx);
16136
16730
  }
16137
16731
  async closePosition(statePda, position, txOptions = {}) {
16138
- const { lbPair, binArrayLower, binArrayUpper } = await this.parsePosition(new web3_js.PublicKey(position));
16732
+ const { lbPair, binArrayLower, binArrayUpper } = await parseMeteoraPosition(this.base.provider.connection, new web3_js.PublicKey(position));
16139
16733
  const glamState = new web3_js.PublicKey(statePda);
16140
16734
  console.log(`close position: ${position}, binArrayLower: ${binArrayLower}, binArrayUpper: ${binArrayUpper}`);
16735
+ // @ts-ignore
16141
16736
  const tx = await this.base.program.methods.meteoraDlmmClosePosition().accounts({
16142
16737
  glamState,
16143
16738
  position: new web3_js.PublicKey(position),
@@ -16146,7 +16741,7 @@ class MeteoraDlmmClient {
16146
16741
  binArrayUpper,
16147
16742
  rentReceiver: this.base.getSigner(),
16148
16743
  eventAuthority: EVENT_AUTHORITY,
16149
- program: METEORA_DLMM
16744
+ program: METEORA_DLMM_PROGRAM
16150
16745
  }).transaction();
16151
16746
  const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
16152
16747
  return await this.base.sendAndConfirm(vTx);
@@ -16164,46 +16759,9 @@ class MeteoraDlmmClient {
16164
16759
  base.toBuffer(),
16165
16760
  lowerBinIdBuffer,
16166
16761
  widthBuffer
16167
- ], METEORA_DLMM);
16762
+ ], METEORA_DLMM_PROGRAM);
16168
16763
  return pda;
16169
16764
  }
16170
- async fetchPositions(owner) {
16171
- const accounts = await this.base.provider.connection.getParsedProgramAccounts(METEORA_DLMM, {
16172
- filters: [
16173
- {
16174
- dataSize: 8120
16175
- },
16176
- {
16177
- memcmp: {
16178
- offset: 40,
16179
- bytes: owner.toBase58()
16180
- }
16181
- }
16182
- ]
16183
- });
16184
- return accounts.map((a)=>a.pubkey);
16185
- }
16186
- async parsePosition(position) {
16187
- const positionAccountInfo = await this.base.provider.connection.getAccountInfo(position);
16188
- if (!positionAccountInfo) {
16189
- throw new Error("Position not found");
16190
- }
16191
- const positionData = positionAccountInfo.data;
16192
- const lbPair = new web3_js.PublicKey(positionData.subarray(8, 40));
16193
- const lowerBinId = positionData.subarray(7912, 7916).readInt32LE();
16194
- const upperBinId = positionData.subarray(7916, 7920).readInt32LE();
16195
- const lowerBinArrayIndex = DLMM.binIdToBinArrayIndex(new anchor.BN(lowerBinId));
16196
- const [binArrayLower] = DLMM.deriveBinArray(lbPair, lowerBinArrayIndex, METEORA_DLMM);
16197
- const upperBinArrayIndex = anchor.BN.max(lowerBinArrayIndex.add(new anchor.BN(1)), DLMM.binIdToBinArrayIndex(new anchor.BN(upperBinId)));
16198
- const [binArrayUpper] = DLMM.deriveBinArray(lbPair, upperBinArrayIndex, METEORA_DLMM);
16199
- return {
16200
- lowerBinId,
16201
- upperBinId,
16202
- binArrayLower,
16203
- binArrayUpper,
16204
- lbPair
16205
- };
16206
- }
16207
16765
  async autoFillY(dlmmPool, amountX) {
16208
16766
  const activeBin = await dlmmPool.getActiveBin();
16209
16767
  const activeBinPricePerToken = dlmmPool.fromPricePerLamport(Number(activeBin.price));
@@ -16448,7 +17006,8 @@ class InvestorClient {
16448
17006
  class PriceClient {
16449
17007
  /**
16450
17008
  * !! This is a convenience method that calculates the AUM of the vault based on priced assets.
16451
- * !! It doesn't reflect the actual AUM of the vault. If the vault has not been priced or pricing data is outdated, the number is NOT meaningful.
17009
+ * !! It doesn't reflect the actual AUM of the vault.
17010
+ * !! If the vault has not been priced or pricing data is outdated, the number is NOT meaningful.
16452
17011
  */ async getAum(glamState) {
16453
17012
  // @ts-ignore
16454
17013
  const glamStateAccount = await this.base.fetchStateAccount(glamState);
@@ -16462,41 +17021,85 @@ class PriceClient {
16462
17021
  });
16463
17022
  return pricedAssets.reduce((sum, p)=>new anchor.BN(p.amount).add(sum), new anchor.BN(0));
16464
17023
  }
16465
- async priceVaultIxs(glamState) {
17024
+ async priceVaultIxs(glamState, priceDenom) {
16466
17025
  const vault = this.base.getVaultPda(glamState);
16467
17026
  const tickets = await fetchMarinadeTicketAccounts(this.base.provider.connection, vault);
16468
- const priceTicketsIx = await this.base.program.methods.priceTickets().accounts({
16469
- glamState
17027
+ // @ts-ignore
17028
+ const priceTicketsIx = await this.base.program.methods.priceTickets(priceDenom).accounts({
17029
+ glamState,
17030
+ solOracle: SOL_ORACLE
16470
17031
  }).remainingAccounts(tickets.map((t)=>({
16471
17032
  pubkey: t.pubkey,
16472
17033
  isSigner: false,
16473
17034
  isWritable: false
16474
17035
  }))).instruction();
16475
17036
  const stakes = await fetchStakeAccounts(this.base.provider.connection, vault);
16476
- const priceStakesIx = await this.base.program.methods.priceStakes().accounts({
16477
- glamState
17037
+ const priceStakesIx = await this.base.program.methods.priceStakes(priceDenom).accounts({
17038
+ glamState,
17039
+ solOracle: SOL_ORACLE
16478
17040
  }).remainingAccounts(stakes.map((s)=>({
16479
17041
  pubkey: s,
16480
17042
  isSigner: false,
16481
17043
  isWritable: false
16482
17044
  }))).instruction();
16483
- const priceVaultIx = await this.base.program.methods.priceVault().accounts({
16484
- glamState
16485
- }).remainingAccounts(await this.remainingAccountsForPricing(glamState)).instruction();
17045
+ const priceVaultIx = await this.base.program.methods.priceVault(priceDenom).accounts({
17046
+ glamState,
17047
+ solOracle: SOL_ORACLE
17048
+ }).remainingAccounts(await this.remainingAccountsForPricingVaultAssets(glamState)).instruction();
17049
+ const priceMeteoraIx = await this.base.program.methods.priceMeteoraPositions(priceDenom).accounts({
17050
+ glamState,
17051
+ solOracle: SOL_ORACLE
17052
+ }).remainingAccounts(await this.remainingAccountsForPricingMeteora(glamState)).instruction();
17053
+ const priceKaminoIx = await this.base.program.methods.priceKaminoObligations(priceDenom).accounts({
17054
+ glamState,
17055
+ solOracle: SOL_ORACLE
17056
+ }).remainingAccounts(await this.remainingAccountsForPricingKamino(glamState)).instruction();
16486
17057
  return [
16487
17058
  priceTicketsIx,
16488
17059
  priceStakesIx,
16489
- priceVaultIx
17060
+ priceVaultIx,
17061
+ priceMeteoraIx,
17062
+ priceKaminoIx
16490
17063
  ];
16491
17064
  }
16492
17065
  constructor(base){
16493
17066
  this.base = base;
16494
- this.remainingAccountsForPricing = async (glamState)=>{
17067
+ this.remainingAccountsForPricingKamino = async (glamState)=>{
17068
+ const glamVault = this.base.getVaultPda(glamState);
17069
+ const obligationAccounts = await fetchKaminoObligations(this.base.provider.connection, glamVault);
17070
+ return obligationAccounts.map((a)=>({
17071
+ pubkey: a,
17072
+ isSigner: false,
17073
+ isWritable: false
17074
+ }));
17075
+ };
17076
+ this.remainingAccountsForPricingMeteora = async (glamState)=>{
17077
+ const glamVault = this.base.getVaultPda(glamState);
17078
+ const positions = await fetchMeteoraPositions(this.base.provider.connection, glamVault);
17079
+ let chunks = await Promise.all(positions.map(async (pubkey)=>{
17080
+ const { lbPair, binArrayLower, binArrayUpper } = await parseMeteoraPosition(this.base.provider.connection, pubkey);
17081
+ return [
17082
+ pubkey,
17083
+ lbPair,
17084
+ binArrayLower,
17085
+ binArrayUpper,
17086
+ new web3_js.PublicKey("3m6i4RFWEDw2Ft4tFHPJtYgmpPe21k56M3FHeWYrgGBz"),
17087
+ new web3_js.PublicKey("9VCioxmni2gDLv11qufWzT3RDERhQE4iY5Gf7NTfYyAV")
17088
+ ].map((k)=>({
17089
+ pubkey: k,
17090
+ isSigner: false,
17091
+ isWritable: false
17092
+ }));
17093
+ }));
17094
+ return chunks.flat();
17095
+ };
17096
+ this.remainingAccountsForPricingVaultAssets = async (glamState)=>{
16495
17097
  const glamStateAccount = await this.base.fetchStateAccount(glamState);
16496
17098
  return glamStateAccount.assets.map((asset)=>[
16497
17099
  this.base.getVaultAta(glamState, asset),
16498
17100
  asset,
16499
- ASSETS_MAINNET.get(asset.toBase58())?.stateAccount || new web3_js.PublicKey(0)
17101
+ // FIXME: check oracle vs LST state?
17102
+ ASSETS_MAINNET.get(asset.toBase58())?.oracle || new web3_js.PublicKey(0)
16500
17103
  ]).flat().map((a)=>({
16501
17104
  pubkey: a,
16502
17105
  isSigner: false,
@@ -16624,7 +17227,10 @@ const getPriorityFeeEstimate = async (heliusApiKey, tx, accountKeys, priorityLev
16624
17227
  return data.result.priorityFeeEstimate;
16625
17228
  };
16626
17229
 
17230
+ exports.ASSETS_MAINNET = ASSETS_MAINNET;
17231
+ exports.ASSETS_TESTS = ASSETS_TESTS;
16627
17232
  exports.BaseClient = BaseClient;
17233
+ exports.ClusterNetwork = ClusterNetwork;
16628
17234
  exports.CompanyModel = CompanyModel;
16629
17235
  exports.CreatedModel = CreatedModel;
16630
17236
  exports.DRIFT_PROGRAM_ID = DRIFT_PROGRAM_ID;
@@ -16648,21 +17254,29 @@ exports.JUPSOL_STAKE_POOL = JUPSOL_STAKE_POOL;
16648
17254
  exports.JUP_VOTE_PROGRAM = JUP_VOTE_PROGRAM;
16649
17255
  exports.JupiterSwapClient = JupiterSwapClient;
16650
17256
  exports.JupiterVoteClient = JupiterVoteClient;
17257
+ exports.KAMINO_FARM_PROGRAM = KAMINO_FARM_PROGRAM;
17258
+ exports.KAMINO_LENDING_PROGRAM = KAMINO_LENDING_PROGRAM;
17259
+ exports.KAMINO_OBTRIGATION_SIZE = KAMINO_OBTRIGATION_SIZE;
16651
17260
  exports.MARINADE_PROGRAM_ID = MARINADE_PROGRAM_ID;
16652
17261
  exports.MARINADE_TICKET_SIZE = MARINADE_TICKET_SIZE;
17262
+ exports.MEMO_PROGRAM = MEMO_PROGRAM;
16653
17263
  exports.MERKLE_DISTRIBUTOR_PROGRAM = MERKLE_DISTRIBUTOR_PROGRAM;
17264
+ exports.METEORA_DLMM_PROGRAM = METEORA_DLMM_PROGRAM;
17265
+ exports.METEORA_POSITION_SIZE = METEORA_POSITION_SIZE;
16654
17266
  exports.MSOL = MSOL;
16655
17267
  exports.ManagerModel = ManagerModel;
16656
17268
  exports.Metadata = Metadata;
16657
17269
  exports.MintIdlModel = MintIdlModel;
16658
17270
  exports.MintModel = MintModel;
16659
17271
  exports.MintOpenfundsModel = MintOpenfundsModel;
17272
+ exports.PriceDenom = PriceDenom;
16660
17273
  exports.SANCTUM_STAKE_POOL_PROGRAM_ID = SANCTUM_STAKE_POOL_PROGRAM_ID;
16661
17274
  exports.SEED_ESCROW = SEED_ESCROW;
16662
17275
  exports.SEED_METADATA = SEED_METADATA;
16663
17276
  exports.SEED_MINT = SEED_MINT;
16664
17277
  exports.SEED_STATE = SEED_STATE;
16665
17278
  exports.SEED_VAULT = SEED_VAULT;
17279
+ exports.SOL_ORACLE = SOL_ORACLE;
16666
17280
  exports.STAKE_ACCOUNT_SIZE = STAKE_ACCOUNT_SIZE;
16667
17281
  exports.StateIdlModel = StateIdlModel;
16668
17282
  exports.StateModel = StateModel;
@@ -16671,10 +17285,13 @@ exports.USDC = USDC;
16671
17285
  exports.WBTC = WBTC;
16672
17286
  exports.WETH = WETH;
16673
17287
  exports.WSOL = WSOL;
17288
+ exports.fetchKaminoObligations = fetchKaminoObligations;
16674
17289
  exports.fetchMarinadeTicketAccounts = fetchMarinadeTicketAccounts;
17290
+ exports.fetchMeteoraPositions = fetchMeteoraPositions;
16675
17291
  exports.fetchStakeAccounts = fetchStakeAccounts;
16676
17292
  exports.getGlamProgram = getGlamProgram;
16677
17293
  exports.getGlamProgramId = getGlamProgramId;
16678
17294
  exports.getPriorityFeeEstimate = getPriorityFeeEstimate;
16679
17295
  exports.getSimulationComputeUnits = getSimulationComputeUnits;
16680
17296
  exports.isBrowser = isBrowser;
17297
+ exports.parseMeteoraPosition = parseMeteoraPosition;