@glamsystems/glam-sdk 0.1.25 → 0.1.27

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
@@ -7,9 +7,9 @@ var splTokenMetadata = require('@solana/spl-token-metadata');
7
7
  var DLMM = require('@meteora-ag/dlmm');
8
8
  var sanctumLstList = require('sanctum-lst-list');
9
9
  var bytes = require('@coral-xyz/anchor/dist/cjs/utils/bytes');
10
+ var borsh = require('@coral-xyz/borsh');
10
11
  var marinadeTsSdk = require('@marinade.finance/marinade-ts-sdk');
11
12
  var splStakePool = require('@solana/spl-stake-pool');
12
- var borsh = require('@coral-xyz/borsh');
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.24",
37
+ version: "0.4.29",
38
38
  spec: "0.1.0",
39
39
  description: "Glam Protocol"
40
40
  };
@@ -1605,16 +1605,16 @@ var instructions = [
1605
1605
  ]
1606
1606
  },
1607
1607
  {
1608
- name: "drift_withdraw",
1608
+ name: "drift_vaults_cancel_request_withdraw",
1609
1609
  discriminator: [
1610
- 86,
1611
- 59,
1612
- 186,
1613
- 123,
1614
- 183,
1615
- 181,
1616
- 234,
1617
- 137
1610
+ 241,
1611
+ 196,
1612
+ 156,
1613
+ 180,
1614
+ 21,
1615
+ 155,
1616
+ 228,
1617
+ 125
1618
1618
  ],
1619
1619
  accounts: [
1620
1620
  {
@@ -1622,7 +1622,69 @@ var instructions = [
1622
1622
  },
1623
1623
  {
1624
1624
  name: "glam_vault",
1625
+ pda: {
1626
+ seeds: [
1627
+ {
1628
+ kind: "const",
1629
+ value: [
1630
+ 118,
1631
+ 97,
1632
+ 117,
1633
+ 108,
1634
+ 116
1635
+ ]
1636
+ },
1637
+ {
1638
+ kind: "account",
1639
+ path: "glam_state"
1640
+ }
1641
+ ]
1642
+ }
1643
+ },
1644
+ {
1645
+ name: "glam_signer",
1625
1646
  writable: true,
1647
+ signer: true
1648
+ },
1649
+ {
1650
+ name: "cpi_program",
1651
+ address: "vAuLTsyrvSfZRuRB3XgvkPwNGgYSs9YRYymVebLKoxR"
1652
+ },
1653
+ {
1654
+ name: "vault",
1655
+ writable: true
1656
+ },
1657
+ {
1658
+ name: "vault_depositor",
1659
+ writable: true
1660
+ },
1661
+ {
1662
+ name: "drift_user_stats"
1663
+ },
1664
+ {
1665
+ name: "drift_user"
1666
+ }
1667
+ ],
1668
+ args: []
1669
+ },
1670
+ {
1671
+ name: "drift_vaults_deposit",
1672
+ discriminator: [
1673
+ 95,
1674
+ 223,
1675
+ 42,
1676
+ 76,
1677
+ 37,
1678
+ 21,
1679
+ 176,
1680
+ 73
1681
+ ],
1682
+ accounts: [
1683
+ {
1684
+ name: "glam_state"
1685
+ },
1686
+ {
1687
+ name: "glam_vault",
1626
1688
  pda: {
1627
1689
  seeds: [
1628
1690
  {
@@ -1649,168 +1711,525 @@ var instructions = [
1649
1711
  },
1650
1712
  {
1651
1713
  name: "cpi_program",
1652
- address: "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
1714
+ address: "vAuLTsyrvSfZRuRB3XgvkPwNGgYSs9YRYymVebLKoxR"
1653
1715
  },
1654
1716
  {
1655
- name: "state"
1717
+ name: "vault",
1718
+ writable: true
1656
1719
  },
1657
1720
  {
1658
- name: "user",
1721
+ name: "vault_depositor",
1659
1722
  writable: true
1660
1723
  },
1661
1724
  {
1662
- name: "user_stats",
1725
+ name: "vault_token_account",
1663
1726
  writable: true
1664
1727
  },
1665
1728
  {
1666
- name: "spot_market_vault",
1729
+ name: "drift_user_stats",
1667
1730
  writable: true
1668
1731
  },
1669
1732
  {
1670
- name: "drift_signer"
1733
+ name: "drift_user",
1734
+ writable: true
1735
+ },
1736
+ {
1737
+ name: "drift_state"
1738
+ },
1739
+ {
1740
+ name: "drift_spot_market_vault",
1741
+ writable: true
1671
1742
  },
1672
1743
  {
1673
1744
  name: "user_token_account",
1674
1745
  writable: true
1675
1746
  },
1747
+ {
1748
+ name: "drift_program"
1749
+ },
1676
1750
  {
1677
1751
  name: "token_program"
1678
1752
  }
1679
1753
  ],
1680
1754
  args: [
1681
- {
1682
- name: "market_index",
1683
- type: "u16"
1684
- },
1685
1755
  {
1686
1756
  name: "amount",
1687
1757
  type: "u64"
1688
- },
1689
- {
1690
- name: "reduce_only",
1691
- type: "bool"
1692
1758
  }
1693
1759
  ]
1694
1760
  },
1695
1761
  {
1696
- name: "emergency_update_mint",
1762
+ name: "drift_vaults_initialize_vault_depositor",
1697
1763
  discriminator: [
1698
- 141,
1699
- 210,
1700
- 26,
1701
- 160,
1702
- 120,
1703
- 140,
1704
- 28,
1705
- 239
1764
+ 109,
1765
+ 183,
1766
+ 50,
1767
+ 62,
1768
+ 60,
1769
+ 195,
1770
+ 192,
1771
+ 51
1706
1772
  ],
1707
1773
  accounts: [
1708
1774
  {
1709
1775
  name: "glam_state",
1710
1776
  writable: true
1711
1777
  },
1778
+ {
1779
+ name: "glam_vault",
1780
+ writable: true,
1781
+ pda: {
1782
+ seeds: [
1783
+ {
1784
+ kind: "const",
1785
+ value: [
1786
+ 118,
1787
+ 97,
1788
+ 117,
1789
+ 108,
1790
+ 116
1791
+ ]
1792
+ },
1793
+ {
1794
+ kind: "account",
1795
+ path: "glam_state"
1796
+ }
1797
+ ]
1798
+ }
1799
+ },
1712
1800
  {
1713
1801
  name: "glam_signer",
1714
1802
  writable: true,
1715
1803
  signer: true
1716
1804
  },
1717
1805
  {
1718
- name: "glam_mint",
1719
- writable: true
1806
+ name: "cpi_program",
1807
+ address: "vAuLTsyrvSfZRuRB3XgvkPwNGgYSs9YRYymVebLKoxR"
1720
1808
  },
1721
1809
  {
1722
- name: "token_2022_program",
1723
- address: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
1724
- }
1725
- ],
1726
- args: [
1810
+ name: "vault"
1811
+ },
1727
1812
  {
1728
- name: "mint_id",
1729
- type: "u8"
1813
+ name: "vault_depositor",
1814
+ writable: true
1730
1815
  },
1731
1816
  {
1732
- name: "mint_model",
1733
- type: {
1734
- defined: {
1735
- name: "MintModel"
1736
- }
1737
- }
1817
+ name: "rent",
1818
+ address: "SysvarRent111111111111111111111111111111111"
1819
+ },
1820
+ {
1821
+ name: "system_program",
1822
+ address: "11111111111111111111111111111111"
1738
1823
  }
1739
- ]
1824
+ ],
1825
+ args: []
1740
1826
  },
1741
1827
  {
1742
- name: "emergency_update_state",
1828
+ name: "drift_vaults_request_withdraw",
1743
1829
  discriminator: [
1744
- 156,
1745
- 211,
1746
- 55,
1747
- 70,
1748
- 92,
1749
- 37,
1750
- 190,
1751
- 66
1830
+ 19,
1831
+ 53,
1832
+ 222,
1833
+ 51,
1834
+ 44,
1835
+ 215,
1836
+ 35,
1837
+ 82
1752
1838
  ],
1753
1839
  accounts: [
1754
1840
  {
1755
- name: "glam_state",
1756
- writable: true
1841
+ name: "glam_state"
1842
+ },
1843
+ {
1844
+ name: "glam_vault",
1845
+ pda: {
1846
+ seeds: [
1847
+ {
1848
+ kind: "const",
1849
+ value: [
1850
+ 118,
1851
+ 97,
1852
+ 117,
1853
+ 108,
1854
+ 116
1855
+ ]
1856
+ },
1857
+ {
1858
+ kind: "account",
1859
+ path: "glam_state"
1860
+ }
1861
+ ]
1862
+ }
1757
1863
  },
1758
1864
  {
1759
1865
  name: "glam_signer",
1760
1866
  writable: true,
1761
1867
  signer: true
1868
+ },
1869
+ {
1870
+ name: "cpi_program",
1871
+ address: "vAuLTsyrvSfZRuRB3XgvkPwNGgYSs9YRYymVebLKoxR"
1872
+ },
1873
+ {
1874
+ name: "vault",
1875
+ writable: true
1876
+ },
1877
+ {
1878
+ name: "vault_depositor",
1879
+ writable: true
1880
+ },
1881
+ {
1882
+ name: "drift_user_stats"
1883
+ },
1884
+ {
1885
+ name: "drift_user"
1762
1886
  }
1763
1887
  ],
1764
1888
  args: [
1765
1889
  {
1766
- name: "state",
1890
+ name: "withdraw_amount",
1891
+ type: "u64"
1892
+ },
1893
+ {
1894
+ name: "withdraw_unit",
1767
1895
  type: {
1768
1896
  defined: {
1769
- name: "StateModel"
1897
+ name: "WithdrawUnit"
1770
1898
  }
1771
1899
  }
1772
1900
  }
1773
1901
  ]
1774
1902
  },
1775
1903
  {
1776
- name: "force_transfer_tokens",
1904
+ name: "drift_vaults_withdraw",
1777
1905
  discriminator: [
1778
- 185,
1779
- 34,
1780
- 78,
1781
- 211,
1782
- 192,
1783
- 13,
1784
- 160,
1785
- 37
1906
+ 58,
1907
+ 127,
1908
+ 150,
1909
+ 177,
1910
+ 66,
1911
+ 45,
1912
+ 5,
1913
+ 30
1786
1914
  ],
1787
1915
  accounts: [
1788
1916
  {
1789
- name: "glam_state",
1790
- writable: true
1791
- },
1792
- {
1793
- name: "glam_signer",
1794
- writable: true,
1795
- signer: true
1796
- },
1797
- {
1798
- name: "glam_mint",
1799
- writable: true
1917
+ name: "glam_state"
1800
1918
  },
1801
1919
  {
1802
- name: "from_ata",
1803
- writable: true,
1920
+ name: "glam_vault",
1804
1921
  pda: {
1805
1922
  seeds: [
1806
1923
  {
1807
- kind: "account",
1808
- path: "from"
1809
- },
1810
- {
1811
- kind: "account",
1812
- path: "token_2022_program"
1813
- },
1924
+ kind: "const",
1925
+ value: [
1926
+ 118,
1927
+ 97,
1928
+ 117,
1929
+ 108,
1930
+ 116
1931
+ ]
1932
+ },
1933
+ {
1934
+ kind: "account",
1935
+ path: "glam_state"
1936
+ }
1937
+ ]
1938
+ }
1939
+ },
1940
+ {
1941
+ name: "glam_signer",
1942
+ writable: true,
1943
+ signer: true
1944
+ },
1945
+ {
1946
+ name: "cpi_program",
1947
+ address: "vAuLTsyrvSfZRuRB3XgvkPwNGgYSs9YRYymVebLKoxR"
1948
+ },
1949
+ {
1950
+ name: "vault",
1951
+ writable: true
1952
+ },
1953
+ {
1954
+ name: "vault_depositor",
1955
+ writable: true
1956
+ },
1957
+ {
1958
+ name: "vault_token_account",
1959
+ writable: true
1960
+ },
1961
+ {
1962
+ name: "drift_user_stats",
1963
+ writable: true
1964
+ },
1965
+ {
1966
+ name: "drift_user",
1967
+ writable: true
1968
+ },
1969
+ {
1970
+ name: "drift_state"
1971
+ },
1972
+ {
1973
+ name: "drift_spot_market_vault",
1974
+ writable: true
1975
+ },
1976
+ {
1977
+ name: "drift_signer"
1978
+ },
1979
+ {
1980
+ name: "user_token_account",
1981
+ writable: true
1982
+ },
1983
+ {
1984
+ name: "drift_program"
1985
+ },
1986
+ {
1987
+ name: "token_program"
1988
+ }
1989
+ ],
1990
+ args: []
1991
+ },
1992
+ {
1993
+ name: "drift_withdraw",
1994
+ discriminator: [
1995
+ 86,
1996
+ 59,
1997
+ 186,
1998
+ 123,
1999
+ 183,
2000
+ 181,
2001
+ 234,
2002
+ 137
2003
+ ],
2004
+ accounts: [
2005
+ {
2006
+ name: "glam_state"
2007
+ },
2008
+ {
2009
+ name: "glam_vault",
2010
+ writable: true,
2011
+ pda: {
2012
+ seeds: [
2013
+ {
2014
+ kind: "const",
2015
+ value: [
2016
+ 118,
2017
+ 97,
2018
+ 117,
2019
+ 108,
2020
+ 116
2021
+ ]
2022
+ },
2023
+ {
2024
+ kind: "account",
2025
+ path: "glam_state"
2026
+ }
2027
+ ]
2028
+ }
2029
+ },
2030
+ {
2031
+ name: "glam_signer",
2032
+ writable: true,
2033
+ signer: true
2034
+ },
2035
+ {
2036
+ name: "cpi_program",
2037
+ address: "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
2038
+ },
2039
+ {
2040
+ name: "state"
2041
+ },
2042
+ {
2043
+ name: "user",
2044
+ writable: true
2045
+ },
2046
+ {
2047
+ name: "user_stats",
2048
+ writable: true
2049
+ },
2050
+ {
2051
+ name: "spot_market_vault",
2052
+ writable: true
2053
+ },
2054
+ {
2055
+ name: "drift_signer"
2056
+ },
2057
+ {
2058
+ name: "user_token_account",
2059
+ writable: true
2060
+ },
2061
+ {
2062
+ name: "token_program"
2063
+ }
2064
+ ],
2065
+ args: [
2066
+ {
2067
+ name: "market_index",
2068
+ type: "u16"
2069
+ },
2070
+ {
2071
+ name: "amount",
2072
+ type: "u64"
2073
+ },
2074
+ {
2075
+ name: "reduce_only",
2076
+ type: "bool"
2077
+ }
2078
+ ]
2079
+ },
2080
+ {
2081
+ name: "emergency_update_mint",
2082
+ discriminator: [
2083
+ 141,
2084
+ 210,
2085
+ 26,
2086
+ 160,
2087
+ 120,
2088
+ 140,
2089
+ 28,
2090
+ 239
2091
+ ],
2092
+ accounts: [
2093
+ {
2094
+ name: "glam_state",
2095
+ writable: true
2096
+ },
2097
+ {
2098
+ name: "glam_signer",
2099
+ writable: true,
2100
+ signer: true
2101
+ },
2102
+ {
2103
+ name: "glam_mint",
2104
+ writable: true
2105
+ },
2106
+ {
2107
+ name: "token_2022_program",
2108
+ address: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
2109
+ }
2110
+ ],
2111
+ args: [
2112
+ {
2113
+ name: "mint_id",
2114
+ type: "u8"
2115
+ },
2116
+ {
2117
+ name: "mint_model",
2118
+ type: {
2119
+ defined: {
2120
+ name: "MintModel"
2121
+ }
2122
+ }
2123
+ }
2124
+ ]
2125
+ },
2126
+ {
2127
+ name: "emergency_update_state",
2128
+ discriminator: [
2129
+ 156,
2130
+ 211,
2131
+ 55,
2132
+ 70,
2133
+ 92,
2134
+ 37,
2135
+ 190,
2136
+ 66
2137
+ ],
2138
+ accounts: [
2139
+ {
2140
+ name: "glam_state",
2141
+ writable: true
2142
+ },
2143
+ {
2144
+ name: "glam_signer",
2145
+ writable: true,
2146
+ signer: true
2147
+ }
2148
+ ],
2149
+ args: [
2150
+ {
2151
+ name: "state",
2152
+ type: {
2153
+ defined: {
2154
+ name: "StateModel"
2155
+ }
2156
+ }
2157
+ }
2158
+ ]
2159
+ },
2160
+ {
2161
+ name: "extend_state",
2162
+ discriminator: [
2163
+ 34,
2164
+ 147,
2165
+ 151,
2166
+ 206,
2167
+ 134,
2168
+ 128,
2169
+ 82,
2170
+ 228
2171
+ ],
2172
+ accounts: [
2173
+ {
2174
+ name: "glam_state",
2175
+ writable: true
2176
+ },
2177
+ {
2178
+ name: "glam_signer",
2179
+ writable: true,
2180
+ signer: true
2181
+ },
2182
+ {
2183
+ name: "system_program",
2184
+ address: "11111111111111111111111111111111"
2185
+ }
2186
+ ],
2187
+ args: [
2188
+ {
2189
+ name: "bytes",
2190
+ type: "u32"
2191
+ }
2192
+ ]
2193
+ },
2194
+ {
2195
+ name: "force_transfer_tokens",
2196
+ discriminator: [
2197
+ 185,
2198
+ 34,
2199
+ 78,
2200
+ 211,
2201
+ 192,
2202
+ 13,
2203
+ 160,
2204
+ 37
2205
+ ],
2206
+ accounts: [
2207
+ {
2208
+ name: "glam_state",
2209
+ writable: true
2210
+ },
2211
+ {
2212
+ name: "glam_signer",
2213
+ writable: true,
2214
+ signer: true
2215
+ },
2216
+ {
2217
+ name: "glam_mint",
2218
+ writable: true
2219
+ },
2220
+ {
2221
+ name: "from_ata",
2222
+ writable: true,
2223
+ pda: {
2224
+ seeds: [
2225
+ {
2226
+ kind: "account",
2227
+ path: "from"
2228
+ },
2229
+ {
2230
+ kind: "account",
2231
+ path: "token_2022_program"
2232
+ },
1814
2233
  {
1815
2234
  kind: "account",
1816
2235
  path: "glam_mint"
@@ -3750,7 +4169,123 @@ var instructions = [
3750
4169
  ],
3751
4170
  accounts: [
3752
4171
  {
3753
- name: "glam_state"
4172
+ name: "glam_state",
4173
+ writable: true
4174
+ },
4175
+ {
4176
+ name: "glam_vault",
4177
+ writable: true,
4178
+ pda: {
4179
+ seeds: [
4180
+ {
4181
+ kind: "const",
4182
+ value: [
4183
+ 118,
4184
+ 97,
4185
+ 117,
4186
+ 108,
4187
+ 116
4188
+ ]
4189
+ },
4190
+ {
4191
+ kind: "account",
4192
+ path: "glam_state"
4193
+ }
4194
+ ]
4195
+ }
4196
+ },
4197
+ {
4198
+ name: "glam_signer",
4199
+ writable: true,
4200
+ signer: true
4201
+ },
4202
+ {
4203
+ name: "cpi_program",
4204
+ address: "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"
4205
+ },
4206
+ {
4207
+ name: "obligation",
4208
+ writable: true
4209
+ },
4210
+ {
4211
+ name: "lending_market"
4212
+ },
4213
+ {
4214
+ name: "lending_market_authority"
4215
+ },
4216
+ {
4217
+ name: "withdraw_reserve",
4218
+ writable: true
4219
+ },
4220
+ {
4221
+ name: "reserve_liquidity_mint"
4222
+ },
4223
+ {
4224
+ name: "reserve_source_collateral",
4225
+ writable: true
4226
+ },
4227
+ {
4228
+ name: "reserve_collateral_mint",
4229
+ writable: true
4230
+ },
4231
+ {
4232
+ name: "reserve_liquidity_supply",
4233
+ writable: true
4234
+ },
4235
+ {
4236
+ name: "user_destination_liquidity",
4237
+ writable: true
4238
+ },
4239
+ {
4240
+ name: "placeholder_user_destination_collateral",
4241
+ optional: true
4242
+ },
4243
+ {
4244
+ name: "collateral_token_program"
4245
+ },
4246
+ {
4247
+ name: "liquidity_token_program"
4248
+ },
4249
+ {
4250
+ name: "instruction_sysvar_account"
4251
+ },
4252
+ {
4253
+ name: "obligation_farm_user_state",
4254
+ writable: true,
4255
+ optional: true
4256
+ },
4257
+ {
4258
+ name: "reserve_farm_state",
4259
+ writable: true,
4260
+ optional: true
4261
+ },
4262
+ {
4263
+ name: "farms_program"
4264
+ }
4265
+ ],
4266
+ args: [
4267
+ {
4268
+ name: "collateral_amount",
4269
+ type: "u64"
4270
+ }
4271
+ ]
4272
+ },
4273
+ {
4274
+ name: "kamino_vaults_deposit",
4275
+ discriminator: [
4276
+ 209,
4277
+ 133,
4278
+ 37,
4279
+ 193,
4280
+ 192,
4281
+ 217,
4282
+ 55,
4283
+ 40
4284
+ ],
4285
+ accounts: [
4286
+ {
4287
+ name: "glam_state",
4288
+ writable: true
3754
4289
  },
3755
4290
  {
3756
4291
  name: "glam_vault",
@@ -3781,86 +4316,68 @@ var instructions = [
3781
4316
  },
3782
4317
  {
3783
4318
  name: "cpi_program",
3784
- address: "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"
4319
+ address: "KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd"
3785
4320
  },
3786
4321
  {
3787
- name: "obligation",
4322
+ name: "vault_state",
3788
4323
  writable: true
3789
4324
  },
3790
4325
  {
3791
- name: "lending_market"
3792
- },
3793
- {
3794
- name: "lending_market_authority"
3795
- },
3796
- {
3797
- name: "withdraw_reserve",
4326
+ name: "token_vault",
3798
4327
  writable: true
3799
4328
  },
3800
4329
  {
3801
- name: "reserve_liquidity_mint"
4330
+ name: "token_mint"
3802
4331
  },
3803
4332
  {
3804
- name: "reserve_source_collateral",
3805
- writable: true
4333
+ name: "base_vault_authority"
3806
4334
  },
3807
4335
  {
3808
- name: "reserve_collateral_mint",
4336
+ name: "shares_mint",
3809
4337
  writable: true
3810
4338
  },
3811
4339
  {
3812
- name: "reserve_liquidity_supply",
4340
+ name: "user_token_ata",
3813
4341
  writable: true
3814
4342
  },
3815
4343
  {
3816
- name: "user_destination_liquidity",
4344
+ name: "user_shares_ata",
3817
4345
  writable: true
3818
4346
  },
3819
4347
  {
3820
- name: "placeholder_user_destination_collateral",
3821
- optional: true
3822
- },
3823
- {
3824
- name: "collateral_token_program"
3825
- },
3826
- {
3827
- name: "liquidity_token_program"
4348
+ name: "klend_program"
3828
4349
  },
3829
4350
  {
3830
- name: "instruction_sysvar_account"
4351
+ name: "token_program"
3831
4352
  },
3832
4353
  {
3833
- name: "obligation_farm_user_state",
3834
- writable: true,
3835
- optional: true
4354
+ name: "shares_token_program"
3836
4355
  },
3837
4356
  {
3838
- name: "reserve_farm_state",
3839
- writable: true,
3840
- optional: true
4357
+ name: "event_authority"
3841
4358
  },
3842
4359
  {
3843
- name: "farms_program"
4360
+ name: "program"
3844
4361
  }
3845
4362
  ],
3846
4363
  args: [
3847
4364
  {
3848
- name: "collateral_amount",
4365
+ name: "amount",
3849
4366
  type: "u64"
3850
4367
  }
3851
4368
  ]
3852
4369
  },
3853
4370
  {
3854
- name: "marinade_claim",
4371
+ name: "kamino_vaults_withdraw",
3855
4372
  discriminator: [
3856
- 54,
3857
- 44,
3858
- 48,
3859
- 204,
3860
- 218,
3861
- 141,
3862
- 36,
3863
- 5
4373
+ 82,
4374
+ 106,
4375
+ 49,
4376
+ 86,
4377
+ 156,
4378
+ 15,
4379
+ 87,
4380
+ 8
3864
4381
  ],
3865
4382
  accounts: [
3866
4383
  {
@@ -3896,29 +4413,95 @@ var instructions = [
3896
4413
  },
3897
4414
  {
3898
4415
  name: "cpi_program",
3899
- address: "MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD"
4416
+ address: "KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd"
3900
4417
  },
3901
4418
  {
3902
- name: "state",
4419
+ name: "withdraw_from_available_vault_state",
3903
4420
  writable: true
3904
4421
  },
3905
4422
  {
3906
- name: "reserve_pda",
4423
+ name: "withdraw_from_available_token_vault",
3907
4424
  writable: true
3908
4425
  },
3909
4426
  {
3910
- name: "ticket_account",
4427
+ name: "withdraw_from_available_base_vault_authority"
4428
+ },
4429
+ {
4430
+ name: "withdraw_from_available_user_token_ata",
3911
4431
  writable: true
3912
4432
  },
3913
4433
  {
3914
- name: "clock"
4434
+ name: "withdraw_from_available_token_mint",
4435
+ writable: true
3915
4436
  },
3916
4437
  {
3917
- name: "system_program",
3918
- address: "11111111111111111111111111111111"
4438
+ name: "withdraw_from_available_user_shares_ata",
4439
+ writable: true
4440
+ },
4441
+ {
4442
+ name: "withdraw_from_available_shares_mint",
4443
+ writable: true
4444
+ },
4445
+ {
4446
+ name: "withdraw_from_available_token_program"
4447
+ },
4448
+ {
4449
+ name: "withdraw_from_available_shares_token_program"
4450
+ },
4451
+ {
4452
+ name: "withdraw_from_available_klend_program"
4453
+ },
4454
+ {
4455
+ name: "withdraw_from_available_event_authority"
4456
+ },
4457
+ {
4458
+ name: "withdraw_from_available_program"
4459
+ },
4460
+ {
4461
+ name: "withdraw_from_reserve_vault_state",
4462
+ writable: true
4463
+ },
4464
+ {
4465
+ name: "withdraw_from_reserve_reserve",
4466
+ writable: true
4467
+ },
4468
+ {
4469
+ name: "withdraw_from_reserve_ctoken_vault",
4470
+ writable: true
4471
+ },
4472
+ {
4473
+ name: "withdraw_from_reserve_lending_market"
4474
+ },
4475
+ {
4476
+ name: "withdraw_from_reserve_lending_market_authority"
4477
+ },
4478
+ {
4479
+ name: "withdraw_from_reserve_reserve_liquidity_supply",
4480
+ writable: true
4481
+ },
4482
+ {
4483
+ name: "withdraw_from_reserve_reserve_collateral_mint",
4484
+ writable: true
4485
+ },
4486
+ {
4487
+ name: "withdraw_from_reserve_reserve_collateral_token_program"
4488
+ },
4489
+ {
4490
+ name: "withdraw_from_reserve_instruction_sysvar_account"
4491
+ },
4492
+ {
4493
+ name: "event_authority"
4494
+ },
4495
+ {
4496
+ name: "program"
3919
4497
  }
3920
4498
  ],
3921
- args: []
4499
+ args: [
4500
+ {
4501
+ name: "amount",
4502
+ type: "u64"
4503
+ }
4504
+ ]
3922
4505
  },
3923
4506
  {
3924
4507
  name: "marinade_deposit",
@@ -4117,88 +4700,6 @@ var instructions = [
4117
4700
  }
4118
4701
  ]
4119
4702
  },
4120
- {
4121
- name: "marinade_order_unstake",
4122
- discriminator: [
4123
- 202,
4124
- 3,
4125
- 33,
4126
- 27,
4127
- 183,
4128
- 156,
4129
- 57,
4130
- 231
4131
- ],
4132
- accounts: [
4133
- {
4134
- name: "glam_state",
4135
- writable: true
4136
- },
4137
- {
4138
- name: "glam_vault",
4139
- writable: true,
4140
- pda: {
4141
- seeds: [
4142
- {
4143
- kind: "const",
4144
- value: [
4145
- 118,
4146
- 97,
4147
- 117,
4148
- 108,
4149
- 116
4150
- ]
4151
- },
4152
- {
4153
- kind: "account",
4154
- path: "glam_state"
4155
- }
4156
- ]
4157
- }
4158
- },
4159
- {
4160
- name: "glam_signer",
4161
- writable: true,
4162
- signer: true
4163
- },
4164
- {
4165
- name: "cpi_program",
4166
- address: "MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD"
4167
- },
4168
- {
4169
- name: "state",
4170
- writable: true
4171
- },
4172
- {
4173
- name: "msol_mint",
4174
- writable: true
4175
- },
4176
- {
4177
- name: "burn_msol_from",
4178
- writable: true
4179
- },
4180
- {
4181
- name: "new_ticket_account",
4182
- writable: true
4183
- },
4184
- {
4185
- name: "clock"
4186
- },
4187
- {
4188
- name: "rent",
4189
- address: "SysvarRent111111111111111111111111111111111"
4190
- },
4191
- {
4192
- name: "token_program"
4193
- }
4194
- ],
4195
- args: [
4196
- {
4197
- name: "msol_amount",
4198
- type: "u64"
4199
- }
4200
- ]
4201
- },
4202
4703
  {
4203
4704
  name: "marinade_withdraw_stake_account",
4204
4705
  discriminator: [
@@ -5757,45 +6258,165 @@ var instructions = [
5757
6258
  writable: true
5758
6259
  },
5759
6260
  {
5760
- name: "policy_account",
6261
+ name: "policy_account",
6262
+ writable: true,
6263
+ optional: true
6264
+ },
6265
+ {
6266
+ name: "system_program",
6267
+ address: "11111111111111111111111111111111"
6268
+ },
6269
+ {
6270
+ name: "token_2022_program",
6271
+ address: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
6272
+ },
6273
+ {
6274
+ name: "policies_program",
6275
+ address: "po1iCYakK3gHCLbuju4wGzFowTMpAJxkqK1iwUqMonY"
6276
+ }
6277
+ ],
6278
+ args: [
6279
+ {
6280
+ name: "mint_id",
6281
+ type: "u8"
6282
+ },
6283
+ {
6284
+ name: "amount",
6285
+ type: "u64"
6286
+ }
6287
+ ]
6288
+ },
6289
+ {
6290
+ name: "price_drift_users",
6291
+ discriminator: [
6292
+ 12,
6293
+ 5,
6294
+ 143,
6295
+ 51,
6296
+ 101,
6297
+ 81,
6298
+ 200,
6299
+ 150
6300
+ ],
6301
+ accounts: [
6302
+ {
6303
+ name: "glam_state",
6304
+ writable: true
6305
+ },
6306
+ {
6307
+ name: "glam_vault",
6308
+ pda: {
6309
+ seeds: [
6310
+ {
6311
+ kind: "const",
6312
+ value: [
6313
+ 118,
6314
+ 97,
6315
+ 117,
6316
+ 108,
6317
+ 116
6318
+ ]
6319
+ },
6320
+ {
6321
+ kind: "account",
6322
+ path: "glam_state"
6323
+ }
6324
+ ]
6325
+ }
6326
+ },
6327
+ {
6328
+ name: "signer",
5761
6329
  writable: true,
5762
- optional: true
5763
- },
5764
- {
5765
- name: "system_program",
5766
- address: "11111111111111111111111111111111"
6330
+ signer: true
5767
6331
  },
5768
6332
  {
5769
- name: "token_2022_program",
5770
- address: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
6333
+ name: "sol_oracle"
5771
6334
  },
5772
6335
  {
5773
- name: "policies_program",
5774
- address: "po1iCYakK3gHCLbuju4wGzFowTMpAJxkqK1iwUqMonY"
6336
+ name: "glam_config",
6337
+ pda: {
6338
+ seeds: [
6339
+ {
6340
+ kind: "const",
6341
+ value: [
6342
+ 103,
6343
+ 108,
6344
+ 111,
6345
+ 98,
6346
+ 97,
6347
+ 108,
6348
+ 95,
6349
+ 99,
6350
+ 111,
6351
+ 110,
6352
+ 102,
6353
+ 105,
6354
+ 103
6355
+ ]
6356
+ }
6357
+ ],
6358
+ program: {
6359
+ kind: "const",
6360
+ value: [
6361
+ 10,
6362
+ 11,
6363
+ 0,
6364
+ 83,
6365
+ 72,
6366
+ 16,
6367
+ 46,
6368
+ 144,
6369
+ 46,
6370
+ 42,
6371
+ 79,
6372
+ 22,
6373
+ 157,
6374
+ 123,
6375
+ 21,
6376
+ 242,
6377
+ 192,
6378
+ 146,
6379
+ 1,
6380
+ 78,
6381
+ 88,
6382
+ 59,
6383
+ 102,
6384
+ 9,
6385
+ 190,
6386
+ 226,
6387
+ 92,
6388
+ 189,
6389
+ 187,
6390
+ 232,
6391
+ 83,
6392
+ 220
6393
+ ]
6394
+ }
6395
+ }
5775
6396
  }
5776
6397
  ],
5777
6398
  args: [
5778
6399
  {
5779
- name: "mint_id",
5780
- type: "u8"
5781
- },
5782
- {
5783
- name: "amount",
5784
- type: "u64"
6400
+ name: "denom",
6401
+ type: {
6402
+ defined: {
6403
+ name: "PriceDenom"
6404
+ }
6405
+ }
5785
6406
  }
5786
6407
  ]
5787
6408
  },
5788
6409
  {
5789
- name: "price_drift",
6410
+ name: "price_drift_vault_depositors",
5790
6411
  discriminator: [
5791
- 240,
5792
- 91,
5793
- 209,
5794
- 89,
5795
- 155,
5796
- 0,
5797
- 97,
5798
- 133
6412
+ 234,
6413
+ 16,
6414
+ 238,
6415
+ 70,
6416
+ 189,
6417
+ 23,
6418
+ 98,
6419
+ 160
5799
6420
  ],
5800
6421
  accounts: [
5801
6422
  {
@@ -5803,7 +6424,25 @@ var instructions = [
5803
6424
  writable: true
5804
6425
  },
5805
6426
  {
5806
- name: "glam_vault"
6427
+ name: "glam_vault",
6428
+ pda: {
6429
+ seeds: [
6430
+ {
6431
+ kind: "const",
6432
+ value: [
6433
+ 118,
6434
+ 97,
6435
+ 117,
6436
+ 108,
6437
+ 116
6438
+ ]
6439
+ },
6440
+ {
6441
+ kind: "account",
6442
+ path: "glam_state"
6443
+ }
6444
+ ]
6445
+ }
5807
6446
  },
5808
6447
  {
5809
6448
  name: "signer",
@@ -5814,13 +6453,66 @@ var instructions = [
5814
6453
  name: "sol_oracle"
5815
6454
  },
5816
6455
  {
5817
- name: "state"
5818
- },
5819
- {
5820
- name: "user"
5821
- },
5822
- {
5823
- name: "user_stats"
6456
+ name: "glam_config",
6457
+ pda: {
6458
+ seeds: [
6459
+ {
6460
+ kind: "const",
6461
+ value: [
6462
+ 103,
6463
+ 108,
6464
+ 111,
6465
+ 98,
6466
+ 97,
6467
+ 108,
6468
+ 95,
6469
+ 99,
6470
+ 111,
6471
+ 110,
6472
+ 102,
6473
+ 105,
6474
+ 103
6475
+ ]
6476
+ }
6477
+ ],
6478
+ program: {
6479
+ kind: "const",
6480
+ value: [
6481
+ 10,
6482
+ 11,
6483
+ 0,
6484
+ 83,
6485
+ 72,
6486
+ 16,
6487
+ 46,
6488
+ 144,
6489
+ 46,
6490
+ 42,
6491
+ 79,
6492
+ 22,
6493
+ 157,
6494
+ 123,
6495
+ 21,
6496
+ 242,
6497
+ 192,
6498
+ 146,
6499
+ 1,
6500
+ 78,
6501
+ 88,
6502
+ 59,
6503
+ 102,
6504
+ 9,
6505
+ 190,
6506
+ 226,
6507
+ 92,
6508
+ 189,
6509
+ 187,
6510
+ 232,
6511
+ 83,
6512
+ 220
6513
+ ]
6514
+ }
6515
+ }
5824
6516
  }
5825
6517
  ],
5826
6518
  args: [
@@ -5873,7 +6565,7 @@ var instructions = [
5873
6565
  }
5874
6566
  },
5875
6567
  {
5876
- name: "glam_signer",
6568
+ name: "signer",
5877
6569
  writable: true,
5878
6570
  signer: true
5879
6571
  },
@@ -5975,16 +6667,16 @@ var instructions = [
5975
6667
  ]
5976
6668
  },
5977
6669
  {
5978
- name: "price_meteora_positions",
6670
+ name: "price_kamino_vault_shares",
5979
6671
  discriminator: [
5980
- 186,
5981
- 22,
5982
- 157,
5983
- 249,
5984
- 185,
5985
- 176,
5986
- 253,
5987
- 133
6672
+ 112,
6673
+ 92,
6674
+ 238,
6675
+ 224,
6676
+ 145,
6677
+ 105,
6678
+ 38,
6679
+ 249
5988
6680
  ],
5989
6681
  accounts: [
5990
6682
  {
@@ -6013,10 +6705,14 @@ var instructions = [
6013
6705
  }
6014
6706
  },
6015
6707
  {
6016
- name: "glam_signer",
6708
+ name: "signer",
6017
6709
  writable: true,
6018
6710
  signer: true
6019
6711
  },
6712
+ {
6713
+ name: "kamino_lending_program",
6714
+ address: "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"
6715
+ },
6020
6716
  {
6021
6717
  name: "sol_oracle"
6022
6718
  },
@@ -6081,6 +6777,22 @@ var instructions = [
6081
6777
  ]
6082
6778
  }
6083
6779
  }
6780
+ },
6781
+ {
6782
+ name: "pyth_oracle",
6783
+ optional: true
6784
+ },
6785
+ {
6786
+ name: "switchboard_price_oracle",
6787
+ optional: true
6788
+ },
6789
+ {
6790
+ name: "switchboard_twap_oracle",
6791
+ optional: true
6792
+ },
6793
+ {
6794
+ name: "scope_prices",
6795
+ optional: true
6084
6796
  }
6085
6797
  ],
6086
6798
  args: [
@@ -6095,16 +6807,16 @@ var instructions = [
6095
6807
  ]
6096
6808
  },
6097
6809
  {
6098
- name: "price_stakes",
6810
+ name: "price_meteora_positions",
6099
6811
  discriminator: [
6100
- 0,
6101
- 60,
6102
- 60,
6103
- 103,
6104
- 201,
6105
- 94,
6106
- 72,
6107
- 223
6812
+ 186,
6813
+ 22,
6814
+ 157,
6815
+ 249,
6816
+ 185,
6817
+ 176,
6818
+ 253,
6819
+ 133
6108
6820
  ],
6109
6821
  accounts: [
6110
6822
  {
@@ -6133,7 +6845,7 @@ var instructions = [
6133
6845
  }
6134
6846
  },
6135
6847
  {
6136
- name: "glam_signer",
6848
+ name: "signer",
6137
6849
  writable: true,
6138
6850
  signer: true
6139
6851
  },
@@ -6215,16 +6927,16 @@ var instructions = [
6215
6927
  ]
6216
6928
  },
6217
6929
  {
6218
- name: "price_tickets",
6930
+ name: "price_stakes",
6219
6931
  discriminator: [
6220
- 253,
6221
- 18,
6222
- 224,
6223
- 98,
6224
- 226,
6225
- 43,
6226
- 65,
6227
- 76
6932
+ 0,
6933
+ 60,
6934
+ 60,
6935
+ 103,
6936
+ 201,
6937
+ 94,
6938
+ 72,
6939
+ 223
6228
6940
  ],
6229
6941
  accounts: [
6230
6942
  {
@@ -6253,7 +6965,7 @@ var instructions = [
6253
6965
  }
6254
6966
  },
6255
6967
  {
6256
- name: "glam_signer",
6968
+ name: "signer",
6257
6969
  writable: true,
6258
6970
  signer: true
6259
6971
  },
@@ -6373,7 +7085,7 @@ var instructions = [
6373
7085
  }
6374
7086
  },
6375
7087
  {
6376
- name: "glam_signer",
7088
+ name: "signer",
6377
7089
  writable: true,
6378
7090
  signer: true
6379
7091
  },
@@ -9512,11 +10224,6 @@ var errors = [
9512
10224
  name: "InvalidAuthority",
9513
10225
  msg: "Invalid authority"
9514
10226
  },
9515
- {
9516
- code: 48009,
9517
- name: "InvalidPriceDenom",
9518
- msg: "Invalid price denom"
9519
- },
9520
10227
  {
9521
10228
  code: 49000,
9522
10229
  name: "InvalidAccountType",
@@ -9717,6 +10424,26 @@ var errors = [
9717
10424
  name: "BaseAssetNotSupported",
9718
10425
  msg: "Base asset must have 6 decimals."
9719
10426
  },
10427
+ {
10428
+ code: 51110,
10429
+ name: "InvalidQuoteSpotMarket",
10430
+ msg: "Unsupported spot market for perp quotes"
10431
+ },
10432
+ {
10433
+ code: 51111,
10434
+ name: "UnknownExternalVaultAsset",
10435
+ msg: "Unknown external vault account"
10436
+ },
10437
+ {
10438
+ code: 51112,
10439
+ name: "InvalidPriceDenom",
10440
+ msg: "Invalid price denom"
10441
+ },
10442
+ {
10443
+ code: 51113,
10444
+ name: "UnexpectedDiscriminator",
10445
+ msg: "Invalid account: discriminator mismatch"
10446
+ },
9720
10447
  {
9721
10448
  code: 52000,
9722
10449
  name: "TransfersDisabled",
@@ -11048,6 +11775,12 @@ var types = [
11048
11775
  },
11049
11776
  {
11050
11777
  name: "MeteoraDlmm"
11778
+ },
11779
+ {
11780
+ name: "DriftVaults"
11781
+ },
11782
+ {
11783
+ name: "KaminoVaults"
11051
11784
  }
11052
11785
  ]
11053
11786
  }
@@ -12168,6 +12901,18 @@ var types = [
12168
12901
  },
12169
12902
  {
12170
12903
  name: "EmergencyUpdate"
12904
+ },
12905
+ {
12906
+ name: "DriftVaultsDeposit"
12907
+ },
12908
+ {
12909
+ name: "DriftVaultsWithdraw"
12910
+ },
12911
+ {
12912
+ name: "KaminoVaultsDeposit"
12913
+ },
12914
+ {
12915
+ name: "KaminoVaultsWithdraw"
12171
12916
  }
12172
12917
  ]
12173
12918
  }
@@ -13024,6 +13769,23 @@ var types = [
13024
13769
  }
13025
13770
  ]
13026
13771
  }
13772
+ },
13773
+ {
13774
+ name: "WithdrawUnit",
13775
+ type: {
13776
+ kind: "enum",
13777
+ variants: [
13778
+ {
13779
+ name: "Shares"
13780
+ },
13781
+ {
13782
+ name: "Token"
13783
+ },
13784
+ {
13785
+ name: "SharesPercent"
13786
+ }
13787
+ ]
13788
+ }
13027
13789
  }
13028
13790
  ];
13029
13791
  var constants = [
@@ -13090,10 +13852,10 @@ const SEED_MINT = (GlamProtocolIdlJson.constants.find((x)=>x.name === "SEED_MINT
13090
13852
  const SEED_STATE = (GlamProtocolIdlJson.constants.find((x)=>x.name === "SEED_STATE")?.value || "").replace(/"/g, "");
13091
13853
  const SEED_VAULT = (GlamProtocolIdlJson.constants.find((x)=>x.name === "SEED_VAULT")?.value || "").replace(/"/g, "");
13092
13854
  const SEED_ESCROW = (GlamProtocolIdlJson.constants.find((x)=>x.name === "SEED_ESCROW")?.value || "").replace(/"/g, "");
13093
- const MARINADE_TICKET_SIZE = 88;
13094
13855
  const STAKE_ACCOUNT_SIZE = 200;
13095
13856
  const METEORA_POSITION_SIZE = 8120;
13096
13857
  const KAMINO_OBTRIGATION_SIZE = 3344;
13858
+ const DRIFT_VAULT_DEPOSITOR_SIZE = 272;
13097
13859
  const JITO_TIP_DEFAULT = new web3_js.PublicKey("96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5");
13098
13860
  const KAMINO_SCOPE_PRICES = new web3_js.PublicKey("3NJYftD5sjVfxSnUdZ1wVML8f3aC6mp1CXCL6L7TnU8C");
13099
13861
  const MARINADE_NATIVE_STAKE_AUTHORITY = new web3_js.PublicKey("stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq");
@@ -13111,6 +13873,7 @@ const JUP = new web3_js.PublicKey("JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN")
13111
13873
  * Program IDs
13112
13874
  */ const MARINADE_PROGRAM_ID = new web3_js.PublicKey("MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD");
13113
13875
  const DRIFT_PROGRAM_ID = new web3_js.PublicKey("dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH");
13876
+ const DRIFT_VAULTS_PROGRAM_ID = new web3_js.PublicKey("vAuLTsyrvSfZRuRB3XgvkPwNGgYSs9YRYymVebLKoxR");
13114
13877
  const JUPITER_PROGRAM_ID = new web3_js.PublicKey("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4");
13115
13878
  const SANCTUM_STAKE_POOL_PROGRAM_ID = new web3_js.PublicKey("SP12tWFxD9oJsVWNavTTBZvMbA6gkAmxtVgxdqvyvhY");
13116
13879
  const GOVERNANCE_PROGRAM_ID = new web3_js.PublicKey("GovaE4iu227srtG2s3tZzB4RmWBzw8sTwrCLZz7kN7rY");
@@ -13119,6 +13882,7 @@ const MERKLE_DISTRIBUTOR_PROGRAM = new web3_js.PublicKey("DiS3nNjFVMieMgmiQFm6wg
13119
13882
  const TRANSFER_HOOK_PROGRAM = new web3_js.PublicKey("po1iCYakK3gHCLbuju4wGzFowTMpAJxkqK1iwUqMonY");
13120
13883
  const METEORA_DLMM_PROGRAM = new web3_js.PublicKey("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo");
13121
13884
  const KAMINO_LENDING_PROGRAM = new web3_js.PublicKey("KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD");
13885
+ const KAMINO_VAULTS_PROGRAM = new web3_js.PublicKey("KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd");
13122
13886
  const KAMINO_FARM_PROGRAM = new web3_js.PublicKey("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
13123
13887
  const MEMO_PROGRAM = new web3_js.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
13124
13888
  /**
@@ -13519,7 +14283,7 @@ var ClusterNetwork = /*#__PURE__*/ function(ClusterNetwork) {
13519
14283
  return ClusterNetwork;
13520
14284
  }({});
13521
14285
 
13522
- const fetchStakeAccounts = async (connection, withdrawAuthority)=>{
14286
+ const findStakeAccounts = async (connection, withdrawAuthority)=>{
13523
14287
  // stake authority offset: 12
13524
14288
  // withdraw authority offset: 44
13525
14289
  const accounts = await connection.getParsedProgramAccounts(web3_js.StakeProgram.programId, {
@@ -13586,43 +14350,6 @@ const getStakeAccountsWithStates = async (connection, withdrawAuthority)=>{
13586
14350
  // order by lamports desc
13587
14351
  return stakes.sort((a, b)=>b.lamports - a.lamports);
13588
14352
  };
13589
- const fetchMarinadeTicketAccounts = async (connection, beneficiary)=>await connection.getProgramAccounts(MARINADE_PROGRAM_ID, {
13590
- filters: [
13591
- {
13592
- dataSize: MARINADE_TICKET_SIZE
13593
- },
13594
- {
13595
- memcmp: {
13596
- offset: 40,
13597
- bytes: beneficiary.toBase58()
13598
- }
13599
- }
13600
- ]
13601
- });
13602
- const fetchKaminoObligations = async (connection, owner, market)=>{
13603
- const accounts = await connection.getProgramAccounts(KAMINO_LENDING_PROGRAM, {
13604
- filters: [
13605
- {
13606
- dataSize: KAMINO_OBTRIGATION_SIZE
13607
- },
13608
- {
13609
- memcmp: {
13610
- offset: 64,
13611
- bytes: owner.toBase58()
13612
- }
13613
- },
13614
- ...market ? [
13615
- {
13616
- memcmp: {
13617
- offset: 32,
13618
- bytes: market.toBase58()
13619
- }
13620
- }
13621
- ] : []
13622
- ]
13623
- });
13624
- return accounts.map((a)=>a.pubkey);
13625
- };
13626
14353
  const fetchMeteoraPositions = async (connection, owner)=>{
13627
14354
  const accounts = await connection.getProgramAccounts(METEORA_DLMM_PROGRAM, {
13628
14355
  filters: [
@@ -13679,6 +14406,22 @@ async function fetchLookupTables(connection, authority, firstEntry) {
13679
14406
  // );
13680
14407
  return [];
13681
14408
  }
14409
+ /**
14410
+ * Parses program logs to extract error message
14411
+ */ function parseProgramLogs(logs) {
14412
+ // "Error Message:" indicates an anchor program error
14413
+ // Other messages are manually sourced & handled
14414
+ const errorMsgLog = (logs || []).find((log)=>log.includes("Error Message:") || log.includes("Error: insufficient funds"));
14415
+ console.log("error message found in program logs", errorMsgLog);
14416
+ if (errorMsgLog) {
14417
+ if (errorMsgLog.includes("Error Message:")) {
14418
+ return errorMsgLog.split("Error Message:")[1].trim();
14419
+ } else {
14420
+ return "Insufficient funds";
14421
+ }
14422
+ }
14423
+ return "Unknown error";
14424
+ }
13682
14425
  const getSimulationComputeUnits = async (connection, instructions, payer, lookupTables)=>{
13683
14426
  const testInstructions = [
13684
14427
  // Set an arbitrarily high number in simulation
@@ -13726,12 +14469,15 @@ const getErrorFromRPCResponse = (rpcResponse)=>{
13726
14469
  const customErrorCode = instructionError[1]["Custom"];
13727
14470
  const { errors: glamErrors } = GlamProtocolIdlJson;
13728
14471
  const glamError = glamErrors.find((e)=>e.code === customErrorCode);
13729
- const msg = glamError?.msg || "Unknown custsom error";
13730
- console.log(`Custom error code: ${customErrorCode}, error: ${msg}}`);
13731
- throw new Error(msg);
14472
+ if (glamError?.msg) {
14473
+ throw new Error(glamError.msg);
14474
+ }
14475
+ // Unrecognized error code, try to parse program logs to get error message
14476
+ const errMsg = parseProgramLogs(rpcResponse.value.logs);
14477
+ throw new Error(errMsg);
13732
14478
  }
13733
14479
  }
13734
- throw Error(error.toString());
14480
+ throw Error("Unknown error");
13735
14481
  }
13736
14482
  };
13737
14483
  const setsAreEqual = (a, b)=>{
@@ -13743,14 +14489,19 @@ const setsAreEqual = (a, b)=>{
13743
14489
  };
13744
14490
 
13745
14491
  const STAKE_POOLS = sanctumLstList.LstList.filter((lst)=>!lst.name.includes("Sanctum Automated") && (lst.pool.program === "Spl" || lst.pool.program === "Marinade" || lst.pool.program === "SanctumSpl" || lst.pool.program === "SanctumSplMulti")).map((lst)=>{
13746
- const { pool, tokenProgram } = lst.pool;
14492
+ const { pool, program } = lst.pool;
14493
+ const poolState = program === "Marinade" ? "8szGkuLTAux9XMgZ2vtY39jVSowEcpBfFfD8hXSEqdGC" : pool;
14494
+ if (!poolState) {
14495
+ throw new Error("Invalid pool state for LST: " + lst.name);
14496
+ }
13747
14497
  return {
13748
14498
  name: lst.name,
13749
14499
  symbol: lst.symbol,
13750
14500
  mint: lst.mint,
14501
+ decimals: lst.decimals,
13751
14502
  logoURI: lst.logoUri,
13752
- tokenProgram,
13753
- poolState: lst.pool.program === "Marinade" ? "8szGkuLTAux9XMgZ2vtY39jVSowEcpBfFfD8hXSEqdGC" : pool || ""
14503
+ tokenProgram: new web3_js.PublicKey(lst.tokenProgram),
14504
+ poolState: new web3_js.PublicKey(poolState)
13754
14505
  };
13755
14506
  });
13756
14507
  const STAKE_POOLS_MAP = new Map(STAKE_POOLS.map((p)=>[
@@ -13901,6 +14652,7 @@ const ASSETS_MAINNET = new Map([
13901
14652
  ]);
13902
14653
  const ASSETS_TESTS = new Map([]);
13903
14654
  const SOL_ORACLE = ASSETS_MAINNET.get("So11111111111111111111111111111111111111112").oracle;
14655
+ const USDC_ORACLE = ASSETS_MAINNET.get("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v").oracle;
13904
14656
 
13905
14657
  class GlamError extends Error {
13906
14658
  constructor(message, rawError, programLogs){
@@ -14074,7 +14826,7 @@ class BaseClient {
14074
14826
  set statePda(statePda) {
14075
14827
  this._statePda = statePda;
14076
14828
  }
14077
- isMainnet() {
14829
+ get isMainnet() {
14078
14830
  return this.cluster === ClusterNetwork.Mainnet;
14079
14831
  }
14080
14832
  isPhantom() {
@@ -14089,7 +14841,7 @@ class BaseClient {
14089
14841
  * @returns Metadata of the asset
14090
14842
  */ getAssetMeta(assetMint) {
14091
14843
  let assetMeta = ASSETS_MAINNET.get(assetMint);
14092
- if (!assetMeta && !this.isMainnet()) {
14844
+ if (!assetMeta && !this.isMainnet) {
14093
14845
  assetMeta = ASSETS_TESTS.get(assetMint);
14094
14846
  }
14095
14847
  if (!assetMeta) {
@@ -14221,18 +14973,10 @@ class BaseClient {
14221
14973
  const errTx = await connection.getTransaction(txSig, {
14222
14974
  maxSupportedTransactionVersion: 0
14223
14975
  });
14224
- throw new GlamError(this.parseProgramLogs(errTx?.meta?.logMessages), errTx?.meta?.err || undefined, errTx?.meta?.logMessages || []);
14976
+ throw new GlamError(parseProgramLogs(errTx?.meta?.logMessages), errTx?.meta?.err || undefined, errTx?.meta?.logMessages || []);
14225
14977
  }
14226
14978
  return txSig;
14227
14979
  }
14228
- parseProgramLogs(logs) {
14229
- const errorMsgLog = (logs || []).find((log)=>log.includes("Error Message:"));
14230
- console.log("error message from program logs", errorMsgLog);
14231
- if (errorMsgLog) {
14232
- return errorMsgLog.split("Error Message:")[1].trim();
14233
- }
14234
- return "Unknown error";
14235
- }
14236
14980
  async getAdressLookupTableAccounts(keys) {
14237
14981
  if (!keys) {
14238
14982
  throw new Error("addressLookupTableAddresses is undefined");
@@ -14487,9 +15231,9 @@ class BaseClient {
14487
15231
  if (stateAccount.mints.length > 0) {
14488
15232
  const mintPubkey = glamStatePda.equals(this.statePda) ? this.mintPda : getMintPda(glamStatePda, 0, this.program.programId);
14489
15233
  const { mint } = await this.fetchMintAndTokenProgram(mintPubkey);
14490
- return StateModel.fromOnchainAccounts(statePda, stateAccount, openfundsMetadataAccount, mint, this.program.programId);
15234
+ return StateModel.fromOnchainAccounts(glamStatePda, stateAccount, openfundsMetadataAccount, mint, this.program.programId);
14491
15235
  }
14492
- return StateModel.fromOnchainAccounts(statePda, stateAccount, openfundsMetadataAccount, undefined, this.program.programId);
15236
+ return StateModel.fromOnchainAccounts(glamStatePda, stateAccount, openfundsMetadataAccount, undefined, this.program.programId);
14493
15237
  }
14494
15238
  /**
14495
15239
  * Fetch all glam state models if no filter options provided
@@ -14709,6 +15453,12 @@ DepositDirection.WITHDRAW = {
14709
15453
  withdraw: {}
14710
15454
  };
14711
15455
  class OracleSource {
15456
+ static fromString(name) {
15457
+ const k = name.slice(0, 1).toLowerCase() + name.slice(1);
15458
+ return {
15459
+ [k]: {}
15460
+ };
15461
+ }
14712
15462
  static get(n) {
14713
15463
  const name = Object.entries(OracleSourceNum).find(([, v])=>v === n)?.[0];
14714
15464
  const source = Object.entries(OracleSource).find(([key, _])=>key.toLocaleLowerCase() === name?.toLocaleLowerCase())?.[1];
@@ -15107,6 +15857,82 @@ SwapReduceOnly.Out = {
15107
15857
  out: {}
15108
15858
  };
15109
15859
 
15860
+ const DriftVaultLayout = borsh.struct([
15861
+ borsh.array(borsh.u8(), 8, "discriminator"),
15862
+ // Basic vault info
15863
+ borsh.array(borsh.u8(), 32, "name"),
15864
+ borsh.publicKey("pubkey"),
15865
+ borsh.publicKey("manager"),
15866
+ borsh.publicKey("tokenAccount"),
15867
+ borsh.publicKey("userStats"),
15868
+ borsh.publicKey("user"),
15869
+ borsh.publicKey("delegate"),
15870
+ borsh.publicKey("liquidationDelegate"),
15871
+ // Share accounting
15872
+ borsh.u128("userShares"),
15873
+ borsh.u128("totalShares"),
15874
+ // Timestamps
15875
+ borsh.i64("lastFeeUpdateTs"),
15876
+ borsh.i64("liquidationStartTs"),
15877
+ borsh.i64("redeemPeriod"),
15878
+ // Withdrawal tracking
15879
+ borsh.u64("totalWithdrawRequested"),
15880
+ // Capacity and fees
15881
+ borsh.u64("maxTokens"),
15882
+ borsh.i64("managementFee"),
15883
+ borsh.i64("initTs"),
15884
+ // Deposit/withdrawal accounting
15885
+ borsh.i64("netDeposits"),
15886
+ borsh.i64("managerNetDeposits"),
15887
+ borsh.u64("totalDeposits"),
15888
+ borsh.u64("totalWithdraws"),
15889
+ borsh.u64("managerTotalDeposits"),
15890
+ borsh.u64("managerTotalWithdraws"),
15891
+ borsh.i64("managerTotalFee"),
15892
+ borsh.i64("managerTotalProfitShare"),
15893
+ borsh.u64("minDepositAmount"),
15894
+ // Manager withdraw request
15895
+ borsh.struct([
15896
+ borsh.u128("shares"),
15897
+ borsh.u64("amount"),
15898
+ borsh.i64("ts")
15899
+ ], "lastManagerWithdrawRequest"),
15900
+ // Configuration
15901
+ borsh.u32("sharesBase"),
15902
+ borsh.u32("profitShare"),
15903
+ borsh.u32("hurdleRate"),
15904
+ borsh.u16("spotMarketIndex"),
15905
+ borsh.u8("bump"),
15906
+ borsh.bool("permissioned"),
15907
+ borsh.bool("vaultProtocol"),
15908
+ borsh.u8("fuelDistributionMode"),
15909
+ borsh.u8("feeUpdateStatus"),
15910
+ borsh.u8("padding1"),
15911
+ borsh.u32("lastCumulativeFuelPerShareTs"),
15912
+ borsh.u128("cumulativeFuelPerShare"),
15913
+ borsh.u128("cumulativeFuel"),
15914
+ // Final padding
15915
+ borsh.array(borsh.u64(), 3, "padding")
15916
+ ]);
15917
+ borsh.struct([
15918
+ borsh.array(borsh.u8(), 8, "discriminator"),
15919
+ borsh.publicKey("marketPda"),
15920
+ borsh.publicKey("oracle"),
15921
+ borsh.publicKey("mint"),
15922
+ borsh.publicKey("vault"),
15923
+ borsh.array(borsh.u8(), 32, "name"),
15924
+ // Padding for bytes between name and cumulativeDepositInterest
15925
+ borsh.array(borsh.u8(), 464 - 168, "padding1"),
15926
+ borsh.u128("cumulativeDepositInterest"),
15927
+ borsh.u128("cumulativeBorrowInterest"),
15928
+ // Padding for bytes between cumulativeBorrowInterest and decimals
15929
+ borsh.array(borsh.u8(), 680 - 496, "padding2"),
15930
+ borsh.u32("decimals"),
15931
+ borsh.u16("marketIndex"),
15932
+ borsh.u8("padding3"),
15933
+ borsh.u8("oracleSource")
15934
+ ]);
15935
+
15110
15936
  function readUnsignedBigInt64LE(buffer, offset) {
15111
15937
  return new anchor.BN(buffer.subarray(offset, offset + 8), 10, "le");
15112
15938
  }
@@ -15566,17 +16392,17 @@ class DriftClient {
15566
16392
  Buffer.from("drift_state")
15567
16393
  ], DRIFT_PROGRAM_ID)[0];
15568
16394
  }
15569
- async fetchAndParseSpotMarket(marketIndex) {
16395
+ async fetchAndParseSpotMarket(marketIndex, skipCache = false) {
15570
16396
  const markets = await this.fetchAndParseSpotMarkets([
15571
16397
  marketIndex
15572
- ]);
16398
+ ], skipCache);
15573
16399
  if (!markets || markets.length === 0) {
15574
16400
  throw new Error(`Spot market not found at index ${marketIndex}`);
15575
16401
  }
15576
16402
  return markets[0];
15577
16403
  }
15578
- async fetchAndParseSpotMarkets(marketIndexes) {
15579
- const indexesToFetch = marketIndexes.filter((marketIndex)=>!this.spotMarkets.has(marketIndex));
16404
+ async fetchAndParseSpotMarkets(marketIndexes, skipCache = false) {
16405
+ const indexesToFetch = marketIndexes.filter((marketIndex)=>skipCache || !this.spotMarkets.has(marketIndex));
15580
16406
  if (indexesToFetch.length > 0) {
15581
16407
  if (process.env.NODE_ENV === "development") {
15582
16408
  console.log("Fetching spot markets:", indexesToFetch);
@@ -15590,20 +16416,26 @@ class DriftClient {
15590
16416
  }
15591
16417
  });
15592
16418
  }
15593
- // At this point this.spotMarkets has all the requested markets
15594
- return marketIndexes.map((marketIndex)=>this.spotMarkets.get(marketIndex)).filter((m)=>m);
16419
+ // At this point this.spotMarkets should have all the requested markets
16420
+ // If not, it means some market indexes are invalid and we throw an error
16421
+ const spotMarkets = marketIndexes.map((marketIndex)=>this.spotMarkets.get(marketIndex)).filter((m)=>m);
16422
+ const invalidIndexes = marketIndexes.filter((marketIndex)=>!this.spotMarkets.has(marketIndex));
16423
+ if (invalidIndexes.length > 0) {
16424
+ console.warn(`The following spot markets could not be found: ${invalidIndexes.join(", ")}`);
16425
+ }
16426
+ return spotMarkets;
15595
16427
  }
15596
- async fetchAndParsePerpMarket(marketIndex) {
16428
+ async fetchAndParsePerpMarket(marketIndex, skipCache = false) {
15597
16429
  const markets = await this.fetchAndParsePerpMarkets([
15598
16430
  marketIndex
15599
- ]);
16431
+ ], skipCache);
15600
16432
  if (!markets || markets.length === 0) {
15601
16433
  throw new Error(`Perp market not found at index ${marketIndex}`);
15602
16434
  }
15603
16435
  return markets[0];
15604
16436
  }
15605
- async fetchAndParsePerpMarkets(marketIndexes) {
15606
- const indexesToFetch = marketIndexes.filter((marketIndex)=>!this.perpMarkets.has(marketIndex));
16437
+ async fetchAndParsePerpMarkets(marketIndexes, skipCache = false) {
16438
+ const indexesToFetch = marketIndexes.filter((marketIndex)=>skipCache || !this.perpMarkets.has(marketIndex));
15607
16439
  if (indexesToFetch.length > 0) {
15608
16440
  if (process.env.NODE_ENV === "development") {
15609
16441
  console.log("Fetching perp markets:", indexesToFetch);
@@ -15621,35 +16453,63 @@ class DriftClient {
15621
16453
  console.log("Requested perp markets already cached:", marketIndexes);
15622
16454
  }
15623
16455
  }
15624
- return marketIndexes.map((marketIndex)=>this.perpMarkets.get(marketIndex)).filter((m)=>m);
15625
- }
15626
- async fetchMarketConfigs() {
15627
- // const response = await fetch(
15628
- // "https://api.glam.systems/v0/drift/market_configs/",
15629
- // );
15630
- // if (!response.ok) {
15631
- // throw new Error(`Failed to fetch market configs: ${response.status}`);
15632
- // }
15633
- // const data = await response.json();
15634
- // const { orderConstants, perp, spot } = data;
15635
- // // Transform perp market from API to `PerpMarket` type
15636
- // const perpMarkets = perp.map((m: any) => ({
15637
- // marketIndex: m.marketIndex,
15638
- // marketPda: m.marketPDA,
15639
- // oracle: new PublicKey(m.oracle),
15640
- // }));
15641
- // // Transform spot market from API to `SpotMarket` type
15642
- // const spotMarkets = spot.map((m: any) => ({
15643
- // marketIndex: m.marketIndex,
15644
- // marketPda: m.marketPDA,
15645
- // oracle: new PublicKey(m.oracle),
15646
- // mint: new PublicKey(m.mint),
15647
- // vault: new PublicKey(m.vaultPDA),
15648
- // decimals: m.decimals,
15649
- // }));
16456
+ const perpMarkets = marketIndexes.map((marketIndex)=>this.perpMarkets.get(marketIndex)).filter((m)=>m);
16457
+ const invalidIndexes = marketIndexes.filter((marketIndex)=>!this.perpMarkets.has(marketIndex));
16458
+ if (invalidIndexes.length > 0) {
16459
+ console.warn(`The following perp markets could not be found: ${invalidIndexes.join(", ")}`);
16460
+ }
16461
+ return perpMarkets;
16462
+ }
16463
+ async fetchMarketConfigs(skipCache = false) {
16464
+ // Attempt to fetch market configs from glam API first
16465
+ const glamApi = process.env.NEXT_PUBLIC_GLAM_API || process.env.GLAM_API;
16466
+ if (glamApi) {
16467
+ const response = await fetch(`${glamApi}/v0/drift/market_configs/`);
16468
+ if (!response.ok) {
16469
+ throw new Error(`Failed to fetch market configs from ${glamApi}: ${response.status}`);
16470
+ }
16471
+ const data = await response.json();
16472
+ const { orderConstants, perp, spot } = data;
16473
+ // Transform perp market from API to `PerpMarket` type
16474
+ const perpMarkets = perp.map((m)=>({
16475
+ name: m.symbol,
16476
+ marketIndex: m.marketIndex,
16477
+ marketPda: new web3_js.PublicKey(m.marketPDA),
16478
+ oracle: new web3_js.PublicKey(m.oracle),
16479
+ oracleSource: OracleSource.fromString(m.oracleSource)
16480
+ }));
16481
+ perpMarkets.forEach((m)=>{
16482
+ this.perpMarkets.set(m.marketIndex, m);
16483
+ });
16484
+ // Transform spot market from API to `SpotMarket` type
16485
+ const spotMarkets = spot.map((m)=>({
16486
+ name: m.symbol,
16487
+ marketIndex: m.marketIndex,
16488
+ marketPda: new web3_js.PublicKey(m.marketPDA),
16489
+ vault: new web3_js.PublicKey(m.vaultPDA),
16490
+ oracle: new web3_js.PublicKey(m.oracle),
16491
+ oracleSource: OracleSource.fromString(m.oracleSource),
16492
+ mint: new web3_js.PublicKey(m.mint),
16493
+ decimals: m.decimals,
16494
+ tokenProgram: new web3_js.PublicKey(m.tokenProgram),
16495
+ cumulativeDepositInterest: new anchor.BN(m.cumulativeDepositInterest),
16496
+ cumulativeBorrowInterest: new anchor.BN(m.cumulativeBorrowInterest)
16497
+ }));
16498
+ spotMarkets.forEach((m)=>{
16499
+ this.spotMarkets.set(m.marketIndex, m);
16500
+ });
16501
+ const marketConfigs = {
16502
+ orderConstants,
16503
+ perpMarkets,
16504
+ spotMarkets
16505
+ };
16506
+ this.marketConfigs = marketConfigs;
16507
+ return marketConfigs;
16508
+ }
16509
+ // If glam API is not available, fetch market configs from RPC
15650
16510
  if (!this.marketConfigs) {
15651
- const perpMarkets = await this.fetchAndParsePerpMarkets(Array.from(Array(100).keys()));
15652
- const spotMarkets = await this.fetchAndParseSpotMarkets(Array.from(Array(100).keys()));
16511
+ const perpMarkets = await this.fetchAndParsePerpMarkets(Array.from(Array(100).keys()), skipCache);
16512
+ const spotMarkets = await this.fetchAndParseSpotMarkets(Array.from(Array(100).keys()), skipCache);
15653
16513
  this.marketConfigs = {
15654
16514
  orderConstants: {
15655
16515
  perpBaseScale: 9,
@@ -15661,24 +16521,10 @@ class DriftClient {
15661
16521
  }
15662
16522
  return this.marketConfigs;
15663
16523
  }
15664
- // public async fetchGlamDriftUser(
15665
- // glamState: PublicKey | string,
15666
- // subAccountId: number = 0,
15667
- // ): Promise<GlamDriftUser> {
15668
- // const vault = this.base.getVaultPda(new PublicKey(glamState));
15669
- // const response = await fetch(
15670
- // `https://api.glam.systems/v0/drift/user?authority=${vault.toBase58()}&accountId=${subAccountId}`,
15671
- // );
15672
- // const data = await response.json();
15673
- // if (!data) {
15674
- // throw new Error("Failed to fetch drift user.");
15675
- // }
15676
- // return data as GlamDriftUser;
15677
- // }
15678
16524
  charsToName(chars) {
15679
16525
  return String.fromCharCode(...chars).replace(/\0/g, "").trim();
15680
16526
  }
15681
- async fetchDriftUser(subAccountId = 0) {
16527
+ async fetchDriftUser(subAccountId = 0, skipCache = false) {
15682
16528
  const { user } = this.getDriftUserPdas(subAccountId);
15683
16529
  const accountInfo = await this.base.provider.connection.getAccountInfo(user);
15684
16530
  if (!accountInfo) {
@@ -15686,7 +16532,7 @@ class DriftClient {
15686
16532
  }
15687
16533
  const { delegate, name, spotPositions, marginMode, perpPositions, isMarginTradingEnabled, maxMarginRatio, orders } = decodeUser(accountInfo.data);
15688
16534
  // Prefetch market configs
15689
- const marketConfigs = await this.fetchMarketConfigs();
16535
+ const marketConfigs = await this.fetchMarketConfigs(skipCache);
15690
16536
  const spotPositionsExt = await Promise.all(spotPositions.map(async (p)=>{
15691
16537
  const { amount, uiAmount } = await this.calcSpotBalance(p.marketIndex, p.scaledBalance, p.balanceType);
15692
16538
  const spotMarket = marketConfigs.spotMarkets.find((m)=>m.marketIndex === p.marketIndex);
@@ -15711,22 +16557,10 @@ class DriftClient {
15711
16557
  maxMarginRatio
15712
16558
  };
15713
16559
  }
15714
- // async getPositions(statePda: PublicKey | string, subAccountId: number = 0) {
15715
- // const driftUser = await this.fetchDriftUser(
15716
- // new PublicKey(statePda),
15717
- // subAccountId,
15718
- // );
15719
- // if (!driftUser) {
15720
- // return { spotPositions: [], perpPositions: [] };
15721
- // }
15722
- // const marketConfigs = await this.fetchMarketConfigs();
15723
- // const { spotPositions, perpPositions } = driftUser;
15724
- // return { spotPositions, perpPositions };
15725
- // }
15726
16560
  /**
15727
16561
  * @deprecated
15728
- */ async fetchPolicyConfig(glamState) {
15729
- const driftUserAccount = glamState && glamState.id && await this.fetchDriftUser();
16562
+ */ async fetchPolicyConfig(stateModel) {
16563
+ const driftUserAccount = await this.fetchDriftUser();
15730
16564
  let delegate = driftUserAccount?.delegate;
15731
16565
  if (delegate && delegate.equals(web3_js.PublicKey.default)) {
15732
16566
  delegate = undefined;
@@ -15734,11 +16568,11 @@ class DriftClient {
15734
16568
  return {
15735
16569
  driftAccessControl: delegate ? 0 : 1,
15736
16570
  driftDelegatedAccount: delegate || null,
15737
- driftMarketIndexesPerp: glamState?.driftMarketIndexesPerp || [],
15738
- driftOrderTypes: glamState?.driftOrderTypes || [],
16571
+ driftMarketIndexesPerp: stateModel?.driftMarketIndexesPerp || [],
16572
+ driftOrderTypes: stateModel?.driftOrderTypes || [],
15739
16573
  driftMaxLeverage: driftUserAccount?.maxMarginRatio ? DRIFT_MARGIN_PRECISION / driftUserAccount?.maxMarginRatio : null,
15740
16574
  driftEnableSpot: driftUserAccount?.isMarginTradingEnabled || false,
15741
- driftMarketIndexesSpot: glamState?.driftMarketIndexesSpot || []
16575
+ driftMarketIndexesSpot: stateModel?.driftMarketIndexesSpot || []
15742
16576
  };
15743
16577
  }
15744
16578
  async composeRemainingAccounts(subAccountId, marketType, marketIndex) {
@@ -15833,7 +16667,8 @@ class DriftClient {
15833
16667
  const glamSigner = txOptions.signer || this.base.getSigner();
15834
16668
  const { user } = this.getDriftUserPdas(subAccountId);
15835
16669
  // https://github.com/drift-labs/protocol-v2/blob/babed162b08b1fe34e49a81c5aa3e4ec0a88ecdf/programs/drift/src/math/constants.rs#L183-L184
15836
- const marginRatio = DRIFT_MARGIN_PRECISION / maxLeverage;
16670
+ // 0 means No Limit
16671
+ const marginRatio = maxLeverage === 0 ? 0 : DRIFT_MARGIN_PRECISION / maxLeverage;
15837
16672
  return await this.base.program.methods.driftUpdateUserCustomMarginRatio(subAccountId, marginRatio).accounts({
15838
16673
  glamState: this.base.statePda,
15839
16674
  glamSigner,
@@ -16082,6 +16917,190 @@ class DriftClient {
16082
16917
  this.marketTypeEquals = (a, b)=>a && Object.keys(a)[0] === Object.keys(b)[0];
16083
16918
  }
16084
16919
  }
16920
+ class DriftVaultsClient {
16921
+ async fetchUserPositions(user) {
16922
+ const accountInfo = await this.base.provider.connection.getAccountInfo(user);
16923
+ if (!accountInfo) {
16924
+ throw new Error(`Drift user ${user} account not found for vault.`);
16925
+ }
16926
+ const { spotPositions, perpPositions } = decodeUser(accountInfo.data);
16927
+ return {
16928
+ perpPositions,
16929
+ spotPositions
16930
+ };
16931
+ }
16932
+ getDepositorPda(driftVault) {
16933
+ return web3_js.PublicKey.findProgramAddressSync([
16934
+ Buffer.from("vault_depositor"),
16935
+ driftVault.toBuffer(),
16936
+ this.base.vaultPda.toBuffer()
16937
+ ], DRIFT_VAULTS_PROGRAM_ID)[0];
16938
+ }
16939
+ async parseDriftVault(driftVault) {
16940
+ const connection = this.base.provider.connection;
16941
+ const accountInfo = await connection.getAccountInfo(driftVault);
16942
+ if (!accountInfo) {
16943
+ throw new Error(`Drift vault account not found: ${driftVault.toBase58()}`);
16944
+ }
16945
+ try {
16946
+ return DriftVaultLayout.decode(accountInfo.data);
16947
+ } catch (error) {
16948
+ throw new Error(`Failed to parse drift vault account: ${error}`);
16949
+ }
16950
+ }
16951
+ async composeRemainingAccounts(user) {
16952
+ const { spotPositions, perpPositions } = await this.fetchUserPositions(user);
16953
+ const spotMarketIndexes = spotPositions.map((p)=>p.marketIndex);
16954
+ const perpMarketIndexes = perpPositions.map((p)=>p.marketIndex);
16955
+ // If there are perp positions, add spot market 0 as it's used as quote market for perp
16956
+ if (perpMarketIndexes.length > 0 && !spotMarketIndexes.includes(0)) {
16957
+ spotMarketIndexes.push(0);
16958
+ }
16959
+ const spotMarkets = await this.drift.fetchAndParseSpotMarkets(spotMarketIndexes);
16960
+ const perpMarkets = await this.drift.fetchAndParsePerpMarkets(perpMarketIndexes);
16961
+ const oracles = spotMarkets.map((m)=>m.oracle).concat(perpMarkets.map((m)=>m.oracle));
16962
+ const markets = spotMarkets.map((m)=>m.marketPda).concat(perpMarkets.map((m)=>m.marketPda));
16963
+ return oracles.map((o)=>({
16964
+ pubkey: new web3_js.PublicKey(o),
16965
+ isWritable: false,
16966
+ isSigner: false
16967
+ })).concat(markets.map((m)=>({
16968
+ pubkey: new web3_js.PublicKey(m),
16969
+ isWritable: true,
16970
+ isSigner: false
16971
+ })));
16972
+ }
16973
+ parseDepositor(depositor, data) {
16974
+ const driftVault = new web3_js.PublicKey(data.subarray(8, 40));
16975
+ const shares = new anchor.BN(data.subarray(104, 112), "le");
16976
+ return {
16977
+ address: depositor,
16978
+ driftVault,
16979
+ shares
16980
+ };
16981
+ }
16982
+ /**
16983
+ * Finds all drift vault depositors
16984
+ */ async findAndParseVaultDepositors(authority) {
16985
+ const accounts = await this.base.provider.connection.getProgramAccounts(DRIFT_VAULTS_PROGRAM_ID, {
16986
+ filters: [
16987
+ {
16988
+ dataSize: DRIFT_VAULT_DEPOSITOR_SIZE
16989
+ },
16990
+ {
16991
+ memcmp: {
16992
+ offset: 72,
16993
+ bytes: (authority || this.base.vaultPda).toBase58()
16994
+ }
16995
+ }
16996
+ ]
16997
+ });
16998
+ return accounts.map((a)=>this.parseDepositor(a.pubkey, a.account.data));
16999
+ }
17000
+ async initializeVaultDepositor(driftVault, txOptions = {}) {
17001
+ const glamSigner = txOptions.signer || this.base.getSigner();
17002
+ const vaultDepositor = this.getDepositorPda(driftVault);
17003
+ const tx = await this.base.program.methods.driftVaultsInitializeVaultDepositor().accounts({
17004
+ glamState: this.base.statePda,
17005
+ glamSigner,
17006
+ vault: driftVault,
17007
+ vaultDepositor
17008
+ }).transaction();
17009
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
17010
+ return await this.base.sendAndConfirm(vTx);
17011
+ }
17012
+ async deposit(driftVault, amount, txOptions = {}) {
17013
+ const glamSigner = txOptions.signer || this.base.getSigner();
17014
+ const vaultDepositor = this.getDepositorPda(driftVault);
17015
+ const { user: driftUser, tokenAccount: vaultTokenAccount, userStats: driftUserStats, spotMarketIndex, vaultProtocol } = await this.parseDriftVault(driftVault);
17016
+ if (vaultProtocol) {
17017
+ throw new Error("Vault protocol fees not supported");
17018
+ }
17019
+ const { vault: driftSpotMarketVault, mint, tokenProgram } = await this.drift.fetchAndParseSpotMarket(spotMarketIndex);
17020
+ const remainingAccounts = await this.composeRemainingAccounts(driftUser);
17021
+ // GLAM vault's token account for deposit, we assume it exists
17022
+ const userTokenAccount = this.base.getVaultAta(mint, tokenProgram);
17023
+ const tx = await this.base.program.methods.driftVaultsDeposit(amount).accounts({
17024
+ glamState: this.base.statePda,
17025
+ glamSigner,
17026
+ vault: driftVault,
17027
+ vaultDepositor,
17028
+ vaultTokenAccount,
17029
+ driftUserStats,
17030
+ driftUser,
17031
+ driftState: this.drift.driftStatePda,
17032
+ driftSpotMarketVault,
17033
+ userTokenAccount,
17034
+ tokenProgram,
17035
+ driftProgram: DRIFT_PROGRAM_ID
17036
+ }).remainingAccounts(remainingAccounts).transaction();
17037
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
17038
+ return await this.base.sendAndConfirm(vTx);
17039
+ }
17040
+ async requestWithdraw(driftVault, amount, txOptions = {}) {
17041
+ const glamSigner = txOptions.signer || this.base.getSigner();
17042
+ const vaultDepositor = this.getDepositorPda(driftVault);
17043
+ const { user: driftUser, userStats: driftUserStats } = await this.parseDriftVault(driftVault);
17044
+ const remainingAccounts = await this.composeRemainingAccounts(driftUser);
17045
+ const tx = await this.base.program.methods.driftVaultsRequestWithdraw(amount, {
17046
+ shares: {}
17047
+ }).accounts({
17048
+ glamState: this.base.statePda,
17049
+ glamSigner,
17050
+ vault: driftVault,
17051
+ vaultDepositor,
17052
+ driftUserStats,
17053
+ driftUser
17054
+ }).remainingAccounts(remainingAccounts).transaction();
17055
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
17056
+ return await this.base.sendAndConfirm(vTx);
17057
+ }
17058
+ async cancelWithdrawRequest(driftVault, txOptions = {}) {
17059
+ const glamSigner = txOptions.signer || this.base.getSigner();
17060
+ const vaultDepositor = this.getDepositorPda(driftVault);
17061
+ const { user: driftUser, userStats: driftUserStats } = await this.parseDriftVault(driftVault);
17062
+ const remainingAccounts = await this.composeRemainingAccounts(driftUser);
17063
+ const tx = await this.base.program.methods.driftVaultsCancelRequestWithdraw().accounts({
17064
+ glamState: this.base.statePda,
17065
+ glamSigner,
17066
+ vault: driftVault,
17067
+ vaultDepositor,
17068
+ driftUserStats,
17069
+ driftUser
17070
+ }).remainingAccounts(remainingAccounts).transaction();
17071
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
17072
+ return await this.base.sendAndConfirm(vTx);
17073
+ }
17074
+ async withdraw(driftVault, txOptions = {}) {
17075
+ const glamSigner = txOptions.signer || this.base.getSigner();
17076
+ const vaultDepositor = this.getDepositorPda(driftVault);
17077
+ const { user: driftUser, userStats: driftUserStats, tokenAccount: vaultTokenAccount, spotMarketIndex } = await this.parseDriftVault(driftVault);
17078
+ const { vault: driftSpotMarketVault, mint, tokenProgram } = await this.drift.fetchAndParseSpotMarket(spotMarketIndex);
17079
+ const userTokenAccount = this.base.getVaultAta(mint, tokenProgram);
17080
+ const remainingAccounts = await this.composeRemainingAccounts(driftUser);
17081
+ const tx = await this.base.program.methods.driftVaultsWithdraw().accounts({
17082
+ glamState: this.base.statePda,
17083
+ glamSigner,
17084
+ vault: driftVault,
17085
+ vaultDepositor,
17086
+ vaultTokenAccount,
17087
+ driftUserStats,
17088
+ driftUser,
17089
+ driftSpotMarketVault,
17090
+ driftSigner: DRIFT_SIGNER,
17091
+ userTokenAccount,
17092
+ driftState: this.drift.driftStatePda,
17093
+ driftProgram: DRIFT_PROGRAM_ID,
17094
+ tokenProgram
17095
+ }).remainingAccounts(remainingAccounts).transaction();
17096
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
17097
+ return await this.base.sendAndConfirm(vTx);
17098
+ }
17099
+ constructor(base, drift){
17100
+ this.base = base;
17101
+ this.drift = drift;
17102
+ }
17103
+ }
16085
17104
 
16086
17105
  const BASE = new web3_js.PublicKey("bJ1TRoFo2P6UHVwqdiipp6Qhp2HaaHpLowZ5LHet8Gm");
16087
17106
  class JupiterSwapClient {
@@ -16153,8 +17172,8 @@ class JupiterSwapClient {
16153
17172
  this.getTokenProgram(inputMint),
16154
17173
  this.getTokenProgram(outputMint)
16155
17174
  ]);
16156
- const inputStakePool = ASSETS_MAINNET.get(inputMint.toBase58())?.oracle || null;
16157
- const outputStakePool = ASSETS_MAINNET.get(outputMint.toBase58())?.oracle || null;
17175
+ const inputStakePool = STAKE_POOLS_MAP.get(inputMint.toBase58())?.poolState || null;
17176
+ const outputStakePool = STAKE_POOLS_MAP.get(outputMint.toBase58())?.poolState || null;
16158
17177
  const preInstructions = await this.getPreInstructions(glamSigner, inputMint, outputMint, amount, inputTokenProgram, outputTokenProgram);
16159
17178
  // @ts-ignore
16160
17179
  const tx = await this.base.program.methods.jupiterSwap(swapIx.data).accounts({
@@ -16492,45 +17511,15 @@ class MarinadeClient {
16492
17511
  const tx = await this.depositStakeAccountTx(stakeAccount, {});
16493
17512
  return await this.base.sendAndConfirm(tx);
16494
17513
  }
16495
- async withdrawStakeAccount(amount, txOptions = {}) {
16496
- const [tx, extraSigner] = await this.withdrawStakeAccountTx(amount, txOptions);
17514
+ async withdrawStakeAccount(amount, deactivate = false, txOptions = {}) {
17515
+ const [tx, extraSigner] = await this.withdrawStakeAccountTx(amount, deactivate, txOptions);
16497
17516
  return await this.base.sendAndConfirm(tx, [
16498
17517
  extraSigner
16499
17518
  ]);
16500
17519
  }
16501
- async orderUnstake(amount, txOptions = {}) {
16502
- const tx = await this.orderUnstakeTx(amount, txOptions);
16503
- return await this.base.sendAndConfirm(tx);
16504
- }
16505
- async claim(tickets, txOptions = {}) {
16506
- const tx = await this.claimTx(tickets, txOptions);
16507
- return await this.base.sendAndConfirm(tx);
16508
- }
16509
17520
  /*
16510
17521
  * Utils
16511
- */ async getTickets() {
16512
- const vault = this.base.vaultPda;
16513
- const accounts = await fetchMarinadeTicketAccounts(this.base.provider.connection, vault);
16514
- return accounts.map((a)=>a.pubkey);
16515
- }
16516
- async getParsedTickets() {
16517
- const vault = this.base.vaultPda;
16518
- const accounts = await fetchMarinadeTicketAccounts(this.base.provider.connection, vault);
16519
- const currentEpoch = await this.base.provider.connection.getEpochInfo();
16520
- return accounts.map((a)=>{
16521
- const lamports = Number(a.account.data.readBigInt64LE(72));
16522
- const createdEpoch = Number(a.account.data.readBigInt64LE(80));
16523
- const isDue = currentEpoch.epoch > createdEpoch;
16524
- return {
16525
- address: a.pubkey,
16526
- lamports,
16527
- createdEpoch,
16528
- isDue,
16529
- isClaimable: isDue && currentEpoch.slotIndex > 5000
16530
- };
16531
- });
16532
- }
16533
- /**
17522
+ */ /**
16534
17523
  * @deprecated Use Marinade.getMarinadeState() instead
16535
17524
  */ get marinadeStateStatic() {
16536
17525
  // The addresses are the same in mainnet and devnet:
@@ -16692,7 +17681,7 @@ class MarinadeClient {
16692
17681
  validatorIndex
16693
17682
  };
16694
17683
  }
16695
- async withdrawStakeAccountTx(amount, txOptions) {
17684
+ async withdrawStakeAccountTx(amount, deactivate = false, txOptions) {
16696
17685
  const glamSigner = txOptions.signer || this.base.getSigner();
16697
17686
  const marinadeState = await this.fetchMarinadeState();
16698
17687
  // Get mariande stake withdraw authority
@@ -16703,79 +17692,39 @@ class MarinadeClient {
16703
17692
  // Fetch stake accounts by withdraw authority
16704
17693
  // Filter by state "active" does not work in localnet tests
16705
17694
  const stakeAccounts = await getStakeAccountsWithStates(this.base.provider.connection, stakeWithdrawAuthority);
16706
- const { stakeIndex, validatorIndex } = await this.getIndexes(stakeAccounts[0], stakeList, validatorList);
17695
+ const idx = this.base.cluster === ClusterNetwork.Mainnet ? stakeAccounts.findIndex((s)=>s.state === "active") : 0;
17696
+ const { stakeIndex, validatorIndex } = await this.getIndexes(stakeAccounts[idx], stakeList, validatorList);
16707
17697
  const burnMsolFrom = this.base.getVaultAta(MSOL);
16708
17698
  const newStake = web3_js.Keypair.generate();
17699
+ const postInstructions = deactivate ? [
17700
+ await this.base.program.methods.stakeDeactivate().accounts({
17701
+ glamSigner,
17702
+ glamState: this.base.statePda,
17703
+ stake: newStake.publicKey
17704
+ }).instruction()
17705
+ ] : [];
16709
17706
  const tx = await this.base.program.methods.marinadeWithdrawStakeAccount(stakeIndex, validatorIndex, amount, this.base.vaultPda).accounts({
16710
17707
  glamState: this.base.statePda,
16711
17708
  glamSigner,
16712
17709
  state: marinadeState.marinadeStateAddress,
16713
17710
  validatorList: validatorList.account,
16714
17711
  stakeList: stakeList.account,
16715
- stakeAccount: stakeAccounts[0].address,
16716
- stakeWithdrawAuthority,
16717
- stakeDepositAuthority,
16718
- treasuryMsolAccount: marinadeState.treasuryMsolAccount,
16719
- msolMint: MSOL,
16720
- burnMsolFrom,
16721
- splitStakeAccount: newStake.publicKey,
16722
- clock: web3_js.SYSVAR_CLOCK_PUBKEY,
16723
- tokenProgram: splToken.TOKEN_PROGRAM_ID,
16724
- stakeProgram: web3_js.StakeProgram.programId
16725
- }).transaction();
16726
- const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
16727
- return [
16728
- vTx,
16729
- newStake
16730
- ];
16731
- }
16732
- async orderUnstakeTx(amount, txOptions) {
16733
- const glamSigner = txOptions.signer || this.base.getSigner();
16734
- const marinadeState = this.marinadeStateStatic;
16735
- const vaultMsolAta = this.base.getVaultAta(marinadeState.msolMintAddress);
16736
- const ticketSeed = Date.now().toString();
16737
- const ticket = await web3_js.PublicKey.createWithSeed(glamSigner, ticketSeed, MARINADE_PROGRAM_ID);
16738
- const lamports = await this.base.provider.connection.getMinimumBalanceForRentExemption(MARINADE_TICKET_SIZE);
16739
- const createTicketIx = web3_js.SystemProgram.createAccountWithSeed({
16740
- fromPubkey: glamSigner,
16741
- newAccountPubkey: ticket,
16742
- basePubkey: glamSigner,
16743
- seed: ticketSeed,
16744
- lamports,
16745
- space: MARINADE_TICKET_SIZE,
16746
- programId: MARINADE_PROGRAM_ID
16747
- });
16748
- const tx = await this.base.program.methods.marinadeOrderUnstake(amount).accounts({
16749
- glamState: this.base.statePda,
16750
- glamSigner,
16751
- newTicketAccount: ticket,
16752
- msolMint: marinadeState.msolMintAddress,
16753
- burnMsolFrom: vaultMsolAta,
16754
- state: marinadeState.marinadeStateAddress,
16755
- clock: web3_js.SYSVAR_CLOCK_PUBKEY,
16756
- tokenProgram: splToken.TOKEN_PROGRAM_ID
16757
- }).preInstructions([
16758
- createTicketIx
16759
- ]).transaction();
16760
- return await this.base.intoVersionedTransaction(tx, txOptions);
16761
- }
16762
- async claimTx(tickets, txOptions) {
16763
- if (tickets.length < 1) {
16764
- throw new Error("At least one ticket is required");
16765
- }
16766
- const glamSigner = txOptions.signer || this.base.getSigner();
16767
- const marinadeState = this.marinadeStateStatic;
16768
- const instructions = await Promise.all(tickets.map((ticket)=>this.base.program.methods.marinadeClaim().accounts({
16769
- glamState: this.base.statePda,
16770
- glamSigner,
16771
- ticketAccount: ticket,
16772
- state: marinadeState.marinadeStateAddress,
16773
- reservePda: marinadeState.reserveAddress,
16774
- clock: web3_js.SYSVAR_CLOCK_PUBKEY
16775
- }).instruction()));
16776
- const tx = new web3_js.Transaction();
16777
- tx.add(...instructions);
16778
- return await this.base.intoVersionedTransaction(tx, txOptions);
17712
+ stakeAccount: stakeAccounts[idx].address,
17713
+ stakeWithdrawAuthority,
17714
+ stakeDepositAuthority,
17715
+ treasuryMsolAccount: marinadeState.treasuryMsolAccount,
17716
+ msolMint: MSOL,
17717
+ burnMsolFrom,
17718
+ splitStakeAccount: newStake.publicKey,
17719
+ clock: web3_js.SYSVAR_CLOCK_PUBKEY,
17720
+ tokenProgram: splToken.TOKEN_PROGRAM_ID,
17721
+ stakeProgram: web3_js.StakeProgram.programId
17722
+ }).postInstructions(postInstructions).transaction();
17723
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
17724
+ return [
17725
+ vTx,
17726
+ newStake
17727
+ ];
16779
17728
  }
16780
17729
  constructor(base){
16781
17730
  this.base = base;
@@ -16931,7 +17880,7 @@ class VaultClient {
16931
17880
  const tx = new web3_js.Transaction().add(splToken.createAssociatedTokenAccountIdempotentInstruction(signer, vaultAta, this.base.vaultPda, asset, tokenProgram), splToken.createTransferCheckedInstruction(signerAta, asset, vaultAta, signer, new anchor.BN(amount).toNumber(), mint.decimals, [], tokenProgram));
16932
17881
  return await this.base.intoVersionedTransaction(tx, txOptions);
16933
17882
  }
16934
- async withdrawIxs(asset, amount, txOptions) {
17883
+ async withdrawIxs(asset, amount, txOptions = {}) {
16935
17884
  const glamSigner = txOptions.signer || this.base.getSigner();
16936
17885
  const { tokenProgram } = await this.base.fetchMintAndTokenProgram(asset);
16937
17886
  const signerAta = this.base.getAta(asset, glamSigner, tokenProgram);
@@ -16968,20 +17917,17 @@ class VaultClient {
16968
17917
  class StakingClient {
16969
17918
  /*
16970
17919
  * Client methods
16971
- */ async unstake(asset, amount, txOptions = {}) {
16972
- const assetStr = asset.toBase58();
17920
+ */ async unstake(asset, amount, deactivate = false, txOptions = {}) {
16973
17921
  // mSOL
16974
- if (assetStr === MSOL.toBase58()) {
16975
- const tx = await this.marinade.orderUnstakeTx(new anchor.BN(amount), txOptions);
16976
- return await this.base.sendAndConfirm(tx);
17922
+ if (asset.equals(MSOL)) {
17923
+ return await this.marinade.withdrawStakeAccount(new anchor.BN(amount), deactivate, txOptions);
16977
17924
  }
16978
17925
  // Other LSTs
16979
- const assetMeta = this.base.getAssetMeta(assetStr);
16980
- if (!assetMeta || !assetMeta.oracle) {
16981
- throw new Error("Invalid LST: " + asset);
17926
+ const stakePool = STAKE_POOLS.find((p)=>p.mint === asset.toBase58());
17927
+ if (!stakePool) {
17928
+ throw new Error(`LST not supported: ${asset}`);
16982
17929
  }
16983
- const tx = await this.stakePoolWithdrawStakeTx(assetMeta.oracle, new anchor.BN(amount), true, txOptions);
16984
- return await this.base.sendAndConfirm(tx);
17930
+ return await this.stakePoolWithdrawStake(stakePool.poolState, new anchor.BN(amount), deactivate, txOptions);
16985
17931
  }
16986
17932
  async stakePoolDepositSol(stakePool, amount, txOptions = {}) {
16987
17933
  const tx = await this.stakePoolDepositSolTx(stakePool, amount, txOptions);
@@ -16991,8 +17937,8 @@ class StakingClient {
16991
17937
  const tx = await this.stakePoolDepositStakeTx(stakePool, stakeAccount, txOptions);
16992
17938
  return await this.base.sendAndConfirm(tx);
16993
17939
  }
16994
- async stakePoolWithdrawStake(stakePool, amount, txOptions = {}) {
16995
- const tx = await this.stakePoolWithdrawStakeTx(stakePool, amount, false, txOptions);
17940
+ async stakePoolWithdrawStake(stakePool, amount, deactivate = false, txOptions = {}) {
17941
+ const tx = await this.stakePoolWithdrawStakeTx(stakePool, amount, deactivate, txOptions);
16996
17942
  return await this.base.sendAndConfirm(tx);
16997
17943
  }
16998
17944
  async initializeAndDelegateStake(vote, amount, txOptions = {}) {
@@ -17210,11 +18156,9 @@ class StakingClient {
17210
18156
  async stakePoolWithdrawStakeTx(stakePool, amount, deactivate = false, txOptions = {}) {
17211
18157
  const glamSigner = txOptions.signer || this.base.getSigner();
17212
18158
  const { programId: stakePoolProgram, poolMint, withdrawAuthority, feeAccount, tokenProgramId: tokenProgram, validatorList, reserveStake } = await this.getStakePoolAccountData(stakePool);
17213
- this.base.vaultPda;
17214
18159
  const poolTokensFrom = this.base.getVaultAta(poolMint, tokenProgram);
17215
18160
  // The reserve stake account should NOT be used for withdrawals unless we have no other options.
17216
18161
  const validatorStakeCandidates = (await getStakeAccountsWithStates(this.base.provider.connection, withdrawAuthority)).filter((s)=>!s.address.equals(reserveStake));
17217
- console.log("validatorStakeCandidates", validatorStakeCandidates);
17218
18162
  const validatorStakeAccount = validatorStakeCandidates.length === 0 ? reserveStake : validatorStakeCandidates[0].address;
17219
18163
  const [stakeAccount, createStakeAccountIx] = await this.createStakeAccount(glamSigner);
17220
18164
  const postInstructions = deactivate ? [
@@ -17466,6 +18410,14 @@ class StateClient {
17466
18410
  }).preInstructions(txOptions.preInstructions || []).transaction();
17467
18411
  return await this.base.intoVersionedTransaction(tx, txOptions);
17468
18412
  }
18413
+ async extend(newBytes, txOptions = {}) {
18414
+ const tx = await this.base.program.methods.extendState(newBytes).accounts({
18415
+ glamState: this.base.statePda,
18416
+ glamSigner: this.base.signer
18417
+ }).transaction();
18418
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
18419
+ return await this.base.sendAndConfirm(vTx);
18420
+ }
17469
18421
  async close(txOptions = {}) {
17470
18422
  const glamSigner = txOptions.signer || this.base.getSigner();
17471
18423
  const tx = await this.base.program.methods.closeState().accounts({
@@ -17857,11 +18809,69 @@ class MintClient {
17857
18809
  }
17858
18810
  }
17859
18811
 
18812
+ const MAX_RESERVES = 25;
18813
+ const VaultAllocationLayout = borsh.struct([
18814
+ borsh.publicKey("reserve"),
18815
+ borsh.publicKey("ctokenVault"),
18816
+ borsh.u64("targetAllocationWeight"),
18817
+ borsh.u64("tokenAllocationCap"),
18818
+ borsh.u64("ctokenVaultBump"),
18819
+ borsh.array(borsh.u64(), 127, "configPadding"),
18820
+ borsh.u64("ctokenAllocation"),
18821
+ borsh.u64("lastInvestSlot"),
18822
+ borsh.u128("tokenTargetAllocationSf"),
18823
+ borsh.array(borsh.u64(), 128, "statePadding")
18824
+ ]);
18825
+ const KVaultStateLayout = borsh.struct([
18826
+ borsh.array(borsh.u8(), 8, "discriminator"),
18827
+ // Admin
18828
+ borsh.publicKey("vaultAdminAuthority"),
18829
+ borsh.publicKey("baseVaultAuthority"),
18830
+ borsh.u64("baseVaultAuthorityBump"),
18831
+ borsh.publicKey("tokenMint"),
18832
+ borsh.u64("tokenMintDecimals"),
18833
+ borsh.publicKey("tokenVault"),
18834
+ borsh.publicKey("tokenProgram"),
18835
+ // shares
18836
+ borsh.publicKey("sharesMint"),
18837
+ borsh.u64("sharesMintDecimals"),
18838
+ // accounting
18839
+ borsh.u64("tokenAvailable"),
18840
+ borsh.u64("sharesIssued"),
18841
+ borsh.u64("availableCrankFunds"),
18842
+ borsh.u64("padding0"),
18843
+ borsh.u64("performanceFeeBps"),
18844
+ borsh.u64("managementFeeBps"),
18845
+ borsh.u64("lastFeeChargeTimestamp"),
18846
+ borsh.u128("prevAumSf"),
18847
+ borsh.u128("pendingFeesSf"),
18848
+ borsh.array(VaultAllocationLayout, MAX_RESERVES, "vaultAllocationStrategy"),
18849
+ borsh.array(borsh.u128(), 256, "padding1"),
18850
+ // General config
18851
+ borsh.u64("minDepositAmount"),
18852
+ borsh.u64("minWithdrawAmount"),
18853
+ borsh.u64("minInvestAmount"),
18854
+ borsh.u64("minInvestDelaySlots"),
18855
+ borsh.u64("crankFundFeePerReserve"),
18856
+ borsh.publicKey("pendingAdmin"),
18857
+ borsh.u128("cumulativeEarnedInterestSf"),
18858
+ borsh.u128("cumulativeMgmtFeesSf"),
18859
+ borsh.u128("cumulativePerfFeesSf"),
18860
+ borsh.array(borsh.u8(), 40, "name"),
18861
+ borsh.publicKey("vaultLookupTable"),
18862
+ borsh.publicKey("vaultFarm"),
18863
+ borsh.u64("creationTimestamp"),
18864
+ borsh.u64("padding2"),
18865
+ borsh.publicKey("allocationAdmin"),
18866
+ borsh.array(borsh.u128(), 242, "padding3")
18867
+ ]);
18868
+
17860
18869
  const LOOKUP_TABLE = new web3_js.PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2");
17861
18870
  const DEFAULT_OBLIGATION_ARGS = {
17862
18871
  tag: 0,
17863
18872
  id: 0
17864
18873
  };
18874
+ const EVENT_AUTHORITY$1 = new web3_js.PublicKey("24tHwQyJJ9akVXxnvkekGfAoeUJXXS7mE6kQNioNySsK");
17865
18875
  function refreshObligation(accounts, programId = KAMINO_LENDING_PROGRAM) {
17866
18876
  const keys = [
17867
18877
  {
@@ -18024,7 +19034,7 @@ function refreshObligationFarmsForReserve(args, accounts, programId = KAMINO_LEN
18024
19034
  const data = Buffer.concat([
18025
19035
  identifier,
18026
19036
  buffer
18027
- ]).slice(0, 8 + len);
19037
+ ]).subarray(0, 8 + len);
18028
19038
  const ix = new web3_js.TransactionInstruction({
18029
19039
  keys,
18030
19040
  programId,
@@ -18123,21 +19133,6 @@ class KaminoLendingClient {
18123
19133
  ], KAMINO_FARM_PROGRAM);
18124
19134
  return obligationFarm;
18125
19135
  }
18126
- async initUserMetadataTx(txOptions = {}) {
18127
- const glamSigner = txOptions.signer || this.base.getSigner();
18128
- const vault = this.base.vaultPda;
18129
- const userMetadata = this.getUserMetadataPda(vault);
18130
- const lookupTable = new web3_js.PublicKey(0); // FIXME: create lookup table
18131
- // @ts-ignore
18132
- const tx = await this.base.program.methods.kaminoLendingInitUserMetadata(lookupTable).accounts({
18133
- glamState: this.base.statePda,
18134
- glamSigner,
18135
- userMetadata,
18136
- referrerUserMetadata: null
18137
- }).transaction();
18138
- const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
18139
- return vTx;
18140
- }
18141
19136
  refreshReserveIxs(lendingMarket, reserves) {
18142
19137
  return reserves.map((reserve)=>refreshReserve({
18143
19138
  reserve,
@@ -18235,26 +19230,7 @@ class KaminoLendingClient {
18235
19230
  feeVault
18236
19231
  };
18237
19232
  }
18238
- /**
18239
- * Fetches and parses obligation account
18240
- *
18241
- * @param obligation User obligation pubkey
18242
- * @returns Pubkeys of reserves for deposits and borrows
18243
- */ async fetchAndParseObligation(obligation) {
18244
- const cached = this.obligations.get(obligation);
18245
- if (cached) {
18246
- return cached;
18247
- }
18248
- const obligationAccount = await this.base.provider.connection.getAccountInfo(obligation);
18249
- if (!obligationAccount) {
18250
- return {
18251
- address: obligation,
18252
- lendingMarket: null,
18253
- deposits: [],
18254
- borrows: []
18255
- };
18256
- }
18257
- const data = obligationAccount.data;
19233
+ parseObligation(obligation, data) {
18258
19234
  const lendingMarket = new web3_js.PublicKey(data.subarray(32, 64));
18259
19235
  // read deposits
18260
19236
  let depositsOffset = 96;
@@ -18284,21 +19260,41 @@ class KaminoLendingClient {
18284
19260
  reserve
18285
19261
  };
18286
19262
  }).filter((d)=>!d.reserve.equals(web3_js.PublicKey.default));
18287
- const parsedObligation = {
19263
+ return {
18288
19264
  address: obligation,
18289
19265
  lendingMarket,
18290
19266
  deposits,
18291
19267
  borrows
18292
19268
  };
18293
- this.obligations.set(obligation, parsedObligation);
19269
+ }
19270
+ /**
19271
+ * Fetches and parses an obligation account
19272
+ */ async fetchAndParseObligation(obligation) {
19273
+ const cached = this.obligations.get(obligation.toBase58());
19274
+ if (cached) {
19275
+ return cached;
19276
+ }
19277
+ const obligationAccount = await this.base.provider.connection.getAccountInfo(obligation);
19278
+ if (!obligationAccount) {
19279
+ return {
19280
+ address: obligation,
19281
+ lendingMarket: null,
19282
+ deposits: [],
19283
+ borrows: []
19284
+ };
19285
+ }
19286
+ const parsedObligation = this.parseObligation(obligation, obligationAccount.data);
19287
+ this.obligations.set(obligation.toBase58(), parsedObligation);
18294
19288
  return parsedObligation;
18295
19289
  }
18296
- _parseReserveAccount(data) {
19290
+ parseReserveAccount(reserve, data) {
18297
19291
  const market = new web3_js.PublicKey(data.subarray(32, 64));
18298
19292
  const farmCollateral = new web3_js.PublicKey(data.subarray(64, 96));
18299
19293
  const farmDebt = new web3_js.PublicKey(data.subarray(96, 128));
18300
19294
  const liquidityMint = new web3_js.PublicKey(data.subarray(128, 160));
18301
19295
  return {
19296
+ address: reserve,
19297
+ market,
18302
19298
  farmCollateral: farmCollateral.equals(web3_js.PublicKey.default) ? null : farmCollateral,
18303
19299
  farmDebt: farmDebt.equals(web3_js.PublicKey.default) ? null : farmDebt,
18304
19300
  liquidityMint,
@@ -18306,19 +19302,28 @@ class KaminoLendingClient {
18306
19302
  };
18307
19303
  }
18308
19304
  async fetchAndParseReserves(reserves) {
18309
- if (this.pubkeyArraysEqual(reserves, Array.from(this.reserves.keys()))) {
18310
- return Array.from(this.reserves.values());
19305
+ const requestReservesSet = new Set(reserves.map((r)=>r.toBase58()));
19306
+ const cachedReservesSet = new Set(this.reserves.keys());
19307
+ // If all requested reserves are cached, return data from cache
19308
+ if ([
19309
+ ...requestReservesSet
19310
+ ].every((r)=>cachedReservesSet.has(r))) {
19311
+ return Array.from(this.reserves.values()).filter((r)=>requestReservesSet.has(r.address.toBase58()));
18311
19312
  }
18312
- const reserveAccounts = await this.base.provider.connection.getMultipleAccountsInfo(reserves);
18313
- if (reserveAccounts.find((a)=>!a)) {
19313
+ // Only fetch reserves that are not cached
19314
+ const reservesToFetch = [
19315
+ ...requestReservesSet
19316
+ ].filter((r)=>!cachedReservesSet.has(r)).map((r)=>new web3_js.PublicKey(r));
19317
+ if (process.env.NODE_ENV !== "production") {
19318
+ console.log("Fetching reserves:", reservesToFetch.map((r)=>r.toBase58()));
19319
+ }
19320
+ const reserveAccounts = await this.base.provider.connection.getMultipleAccountsInfo(reservesToFetch);
19321
+ if (reserveAccounts.some((a)=>!a)) {
18314
19322
  throw new Error("Not all reserves can be found");
18315
19323
  }
18316
- return reserveAccounts.filter((a)=>!!a).map((account, i)=>{
18317
- const parsedReserve = {
18318
- address: reserves[i],
18319
- ...this._parseReserveAccount(account.data)
18320
- };
18321
- this.reserves.set(reserves[i], parsedReserve);
19324
+ return reserveAccounts.map((account, i)=>{
19325
+ const parsedReserve = this.parseReserveAccount(reserves[i], account.data);
19326
+ this.reserves.set(reserves[i].toBase58(), parsedReserve);
18322
19327
  return parsedReserve;
18323
19328
  });
18324
19329
  }
@@ -18345,14 +19350,55 @@ class KaminoLendingClient {
18345
19350
  if (accounts.length === 0) {
18346
19351
  throw new Error("Reserve not found");
18347
19352
  }
18348
- const account = accounts[0];
18349
- const parsedReserve = {
18350
- address: account.pubkey,
18351
- ...this._parseReserveAccount(account.account.data)
18352
- };
18353
- this.reserves.set(account.pubkey, parsedReserve);
19353
+ const parsedReserve = this.parseReserveAccount(accounts[0].pubkey, accounts[0].account.data);
19354
+ this.reserves.set(accounts[0].pubkey.toBase58(), parsedReserve);
18354
19355
  return parsedReserve;
18355
19356
  }
19357
+ /**
19358
+ * Finds and parses Kamino obligations for a given owner and market (optional)
19359
+ */ async findAndParseObligations(owner, market) {
19360
+ const accounts = await this.base.provider.connection.getProgramAccounts(KAMINO_LENDING_PROGRAM, {
19361
+ filters: [
19362
+ {
19363
+ dataSize: KAMINO_OBTRIGATION_SIZE
19364
+ },
19365
+ {
19366
+ memcmp: {
19367
+ offset: 64,
19368
+ bytes: owner.toBase58()
19369
+ }
19370
+ },
19371
+ ...market ? [
19372
+ {
19373
+ memcmp: {
19374
+ offset: 32,
19375
+ bytes: market.toBase58()
19376
+ }
19377
+ }
19378
+ ] : []
19379
+ ]
19380
+ });
19381
+ // Parse obligations and cache them
19382
+ return accounts.map((a)=>{
19383
+ const parsedObligation = this.parseObligation(a.pubkey, a.account.data);
19384
+ this.obligations.set(a.pubkey.toBase58(), parsedObligation);
19385
+ return parsedObligation;
19386
+ });
19387
+ }
19388
+ async initUserMetadataTx(txOptions = {}) {
19389
+ const glamSigner = txOptions.signer || this.base.getSigner();
19390
+ const vault = this.base.vaultPda;
19391
+ const userMetadata = this.getUserMetadataPda(vault);
19392
+ const lookupTable = new web3_js.PublicKey(0); // FIXME: create lookup table
19393
+ const tx = await this.base.program.methods.kaminoLendingInitUserMetadata(lookupTable).accounts({
19394
+ glamState: this.base.statePda,
19395
+ glamSigner,
19396
+ userMetadata,
19397
+ referrerUserMetadata: null
19398
+ }).transaction();
19399
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
19400
+ return vTx;
19401
+ }
18356
19402
  async depositTx(market, asset, amount, txOptions) {
18357
19403
  const glamSigner = txOptions.signer || this.base.getSigner();
18358
19404
  const vault = this.base.vaultPda;
@@ -18866,6 +19912,160 @@ class KaminoFarmClient {
18866
19912
  ], KAMINO_FARM_PROGRAM)[0];
18867
19913
  }
18868
19914
  }
19915
+ class KaminoVaultsClient {
19916
+ async deposit(vault, amount, txOptions = {}) {
19917
+ const tx = await this.depositTx(vault, amount, txOptions);
19918
+ return await this.base.sendAndConfirm(tx);
19919
+ }
19920
+ async withdraw(vault, amount, txOptions = {}) {
19921
+ const tx = await this.withdrawTx(vault, amount, txOptions);
19922
+ return await this.base.sendAndConfirm(tx);
19923
+ }
19924
+ async findAndParseKaminoVaults() {
19925
+ const accounts = await this.base.provider.connection.getProgramAccounts(KAMINO_VAULTS_PROGRAM, {
19926
+ filters: [
19927
+ {
19928
+ dataSize: 62552
19929
+ },
19930
+ {
19931
+ memcmp: {
19932
+ offset: 0,
19933
+ bytes: "5MRSpWLS65g=",
19934
+ encoding: "base64"
19935
+ }
19936
+ }
19937
+ ]
19938
+ });
19939
+ if (accounts.length === 0) {
19940
+ throw new Error("Kamino vaults not found");
19941
+ }
19942
+ return accounts.map((a)=>{
19943
+ const vaultState = KVaultStateLayout.decode(a.account.data);
19944
+ this.vaultStates.set(a.pubkey.toBase58(), vaultState);
19945
+ this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), a.pubkey);
19946
+ return vaultState;
19947
+ });
19948
+ }
19949
+ async getVaultPdasByShareMints(mints) {
19950
+ if (this.vaultStates.size === 0) {
19951
+ await this.findAndParseKaminoVaults();
19952
+ }
19953
+ return mints.map((mint)=>this.shareMintToVaultPdaMap.get(mint.toBase58()));
19954
+ }
19955
+ async fetchAndParseVaultState(vault) {
19956
+ const vaultAccount = await this.base.provider.connection.getAccountInfo(vault);
19957
+ if (!vaultAccount) {
19958
+ throw new Error(`Kamino vault account not found:, ${vault}`);
19959
+ }
19960
+ const vaultState = KVaultStateLayout.decode(vaultAccount.data);
19961
+ this.vaultStates.set(vault.toBase58(), vaultState);
19962
+ this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), vault);
19963
+ return vaultState;
19964
+ }
19965
+ async composeRemainingAccounts(allocationStrategies) {
19966
+ // For each allocation get reserve and market pubkeys
19967
+ const reserves = allocationStrategies.map((strategy)=>strategy.reserve);
19968
+ const parsedReserves = await this.kaminoLending.fetchAndParseReserves(reserves);
19969
+ const reserveMetas = reserves.map((pubkey)=>({
19970
+ pubkey,
19971
+ isSigner: false,
19972
+ isWritable: true
19973
+ }));
19974
+ const marketMetas = parsedReserves.map(({ market })=>({
19975
+ pubkey: market,
19976
+ isSigner: false,
19977
+ isWritable: false
19978
+ }));
19979
+ return [
19980
+ ...reserveMetas,
19981
+ ...marketMetas
19982
+ ];
19983
+ }
19984
+ async depositTx(vault, amount, txOptions = {}) {
19985
+ const glamSigner = txOptions.signer || this.base.getSigner();
19986
+ const vaultState = await this.fetchAndParseVaultState(vault);
19987
+ const amountBN = new anchor.BN(amount * 10 ** vaultState.tokenMintDecimals.toNumber());
19988
+ const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
19989
+ const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
19990
+ const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
19991
+ // Create user shares ata
19992
+ const preInstructions = [
19993
+ splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, userSharesAta, this.base.vaultPda, vaultState.sharesMint, sharesTokenProgram)
19994
+ ];
19995
+ // Remaining accounts, skip empty allocation strategies
19996
+ const remainingAccounts = await this.composeRemainingAccounts(vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(web3_js.PublicKey.default)));
19997
+ const tx = await this.base.program.methods.kaminoVaultsDeposit(amountBN).accounts({
19998
+ glamState: this.base.statePda,
19999
+ glamSigner,
20000
+ vaultState: vault,
20001
+ tokenVault: vaultState.tokenVault,
20002
+ tokenMint: vaultState.tokenMint,
20003
+ baseVaultAuthority: vaultState.baseVaultAuthority,
20004
+ sharesMint: vaultState.sharesMint,
20005
+ userTokenAta,
20006
+ userSharesAta,
20007
+ klendProgram: KAMINO_LENDING_PROGRAM,
20008
+ tokenProgram: vaultState.tokenProgram,
20009
+ sharesTokenProgram,
20010
+ eventAuthority: EVENT_AUTHORITY$1,
20011
+ program: KAMINO_VAULTS_PROGRAM
20012
+ }).remainingAccounts(remainingAccounts).preInstructions(preInstructions).transaction();
20013
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20014
+ return vTx;
20015
+ }
20016
+ async withdrawTx(vault, amount, txOptions = {}) {
20017
+ const glamSigner = txOptions.signer || this.base.getSigner();
20018
+ const vaultState = await this.fetchAndParseVaultState(vault);
20019
+ const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
20020
+ const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
20021
+ const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
20022
+ const amountBN = new anchor.BN(amount * 10 ** vaultState.sharesMintDecimals.toNumber());
20023
+ const reserves = vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(web3_js.PublicKey.default));
20024
+ // Withdraw from the first reserve when kvault does not have enough liquidity
20025
+ const idx = 0;
20026
+ const withdrawReserve = (await this.kaminoLending.fetchAndParseReserves(reserves.map((r)=>r.reserve)))[idx];
20027
+ const vaultCollateralTokenVault = vaultState.vaultAllocationStrategy[idx].ctokenVault;
20028
+ const remainingAccounts = await this.composeRemainingAccounts(reserves);
20029
+ const preInstructions = [
20030
+ splToken.createAssociatedTokenAccountIdempotentInstruction(glamSigner, userTokenAta, this.base.vaultPda, vaultState.tokenMint, vaultState.tokenProgram)
20031
+ ];
20032
+ const tx = await this.base.program.methods.kaminoVaultsWithdraw(amountBN).accounts({
20033
+ glamState: this.base.statePda,
20034
+ glamSigner,
20035
+ withdrawFromAvailableVaultState: vault,
20036
+ withdrawFromAvailableTokenVault: vaultState.tokenVault,
20037
+ withdrawFromAvailableBaseVaultAuthority: vaultState.baseVaultAuthority,
20038
+ withdrawFromAvailableUserTokenAta: userTokenAta,
20039
+ withdrawFromAvailableTokenMint: vaultState.tokenMint,
20040
+ withdrawFromAvailableUserSharesAta: userSharesAta,
20041
+ withdrawFromAvailableSharesMint: vaultState.sharesMint,
20042
+ withdrawFromAvailableTokenProgram: vaultState.tokenProgram,
20043
+ withdrawFromAvailableSharesTokenProgram: sharesTokenProgram,
20044
+ withdrawFromAvailableKlendProgram: KAMINO_LENDING_PROGRAM,
20045
+ withdrawFromAvailableEventAuthority: EVENT_AUTHORITY$1,
20046
+ withdrawFromAvailableProgram: KAMINO_VAULTS_PROGRAM,
20047
+ withdrawFromReserveVaultState: vault,
20048
+ withdrawFromReserveReserve: withdrawReserve.address,
20049
+ withdrawFromReserveCtokenVault: vaultCollateralTokenVault,
20050
+ withdrawFromReserveLendingMarket: withdrawReserve.market,
20051
+ withdrawFromReserveLendingMarketAuthority: this.kaminoLending.getMarketAuthority(withdrawReserve.market),
20052
+ withdrawFromReserveReserveLiquiditySupply: withdrawReserve.liquiditySupplyVault,
20053
+ withdrawFromReserveReserveCollateralMint: withdrawReserve.collateralMint,
20054
+ withdrawFromReserveReserveCollateralTokenProgram: splToken.TOKEN_PROGRAM_ID,
20055
+ withdrawFromReserveInstructionSysvarAccount: web3_js.SYSVAR_INSTRUCTIONS_PUBKEY,
20056
+ eventAuthority: EVENT_AUTHORITY$1,
20057
+ program: KAMINO_VAULTS_PROGRAM
20058
+ }).remainingAccounts(remainingAccounts).preInstructions(preInstructions).transaction();
20059
+ const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
20060
+ return vTx;
20061
+ }
20062
+ constructor(base, kaminoLending){
20063
+ this.base = base;
20064
+ this.kaminoLending = kaminoLending;
20065
+ this.vaultStates = new Map();
20066
+ this.shareMintToVaultPdaMap = new Map();
20067
+ }
20068
+ }
18869
20069
 
18870
20070
  // Pubkey::find_program_address(&[b"__event_authority"], &dlmm_interface::ID)
18871
20071
  const EVENT_AUTHORITY = new web3_js.PublicKey("D1ZN9Wj1fRSUQfCjhvnu1hqDMT7hzjzBBpi12nVniYD6");
@@ -19331,14 +20531,17 @@ class PriceClient {
19331
20531
  * !! If the vault has not been priced or pricing data is outdated, the number is NOT meaningful.
19332
20532
  */ async getAum() {
19333
20533
  console.warn("getAum() should only be used for testing. It doesn't reflect the actual AUM of the vault in production.");
19334
- // @ts-ignore
19335
20534
  const stateModel = await this.base.fetchStateModel();
19336
20535
  return (stateModel?.pricedAssets || []).reduce((sum, p)=>new anchor.BN(p.amount).add(sum), new anchor.BN(0));
19337
20536
  }
19338
- async priceKaminoIx(priceDenom) {
19339
- const glamVault = this.base.vaultPda;
19340
- const obligations = await fetchKaminoObligations(this.base.provider.connection, glamVault);
19341
- const parsedObligations = await Promise.all(obligations.map((o)=>this.klend.fetchAndParseObligation(o)));
20537
+ /**
20538
+ * Returns an instruction that prices Kamino obligations.
20539
+ * If there are no Kamino obligations, returns null.
20540
+ */ async priceKaminoObligationsIx(priceDenom) {
20541
+ const parsedObligations = await this.klend.findAndParseObligations(this.base.vaultPda);
20542
+ if (parsedObligations.length === 0) {
20543
+ return null;
20544
+ }
19342
20545
  const pubkeySet = new Set([]);
19343
20546
  parsedObligations.filter((o)=>o.lendingMarket !== null).map((o)=>{
19344
20547
  pubkeySet.add(o.address.toBase58());
@@ -19351,7 +20554,6 @@ class PriceClient {
19351
20554
  isSigner: false,
19352
20555
  isWritable: true
19353
20556
  }));
19354
- // @ts-ignore
19355
20557
  const priceIx = await this.base.program.methods.priceKaminoObligations(priceDenom).accounts({
19356
20558
  glamState: this.base.statePda,
19357
20559
  solOracle: SOL_ORACLE,
@@ -19362,81 +20564,193 @@ class PriceClient {
19362
20564
  }).remainingAccounts(remainingAccounts).instruction();
19363
20565
  return priceIx;
19364
20566
  }
19365
- async priceVaultIxs(priceDenom) {
19366
- const glamVault = this.base.vaultPda;
19367
- const priceVaultIx = await this.base.program.methods.priceVault(priceDenom).accounts({
20567
+ async priceKaminoVaultSharesIx(priceDenom) {
20568
+ const allKvaultStates = await this.kvaults.findAndParseKaminoVaults();
20569
+ const allKvaultMints = allKvaultStates.map((kvault)=>kvault.sharesMint);
20570
+ // All share token accounts GLAM vault could possibly hold
20571
+ const possibleShareAtas = allKvaultMints.map((mint)=>this.base.getVaultAta(mint));
20572
+ const possibleShareAtaAccountsInfo = await this.base.provider.connection.getMultipleAccountsInfo(possibleShareAtas);
20573
+ const shareAtas = [];
20574
+ const shareMints = [];
20575
+ const kvaultStates = [];
20576
+ possibleShareAtaAccountsInfo.forEach((info, i)=>{
20577
+ if (info !== null) {
20578
+ shareAtas.push(possibleShareAtas[i]);
20579
+ shareMints.push(allKvaultMints[i]);
20580
+ kvaultStates.push(allKvaultStates[i]);
20581
+ }
20582
+ });
20583
+ const kvaultPdas = await this.kvaults.getVaultPdasByShareMints(shareMints);
20584
+ const remainingAccounts = (await Promise.all(kvaultStates.map((kvault)=>{
20585
+ return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(web3_js.PublicKey.default)));
20586
+ }))).flat();
20587
+ [
20588
+ ...kvaultPdas,
20589
+ ...shareAtas
20590
+ ].map((pubkey)=>{
20591
+ remainingAccounts.unshift({
20592
+ pubkey: pubkey,
20593
+ isSigner: false,
20594
+ isWritable: false
20595
+ });
20596
+ });
20597
+ const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom).accounts({
19368
20598
  glamState: this.base.statePda,
19369
- solOracle: SOL_ORACLE
19370
- }).remainingAccounts(await this.remainingAccountsForPricingVaultAssets(priceDenom == PriceDenom.ASSET)).instruction();
19371
- // If priceDenom is ASSET, only priceVaultIx is returned
19372
- // We currently don't support pricing other assets in custom base asset
19373
- // due to the lack of oracles
19374
- if (priceDenom == PriceDenom.ASSET) {
19375
- return [
19376
- priceVaultIx
19377
- ];
20599
+ solOracle: SOL_ORACLE,
20600
+ pythOracle: null,
20601
+ switchboardPriceOracle: null,
20602
+ switchboardTwapOracle: null,
20603
+ scopePrices: KAMINO_SCOPE_PRICES
20604
+ }).remainingAccounts(remainingAccounts).instruction();
20605
+ return priceIx;
20606
+ }
20607
+ /**
20608
+ * Returns an instruction that prices the all Drift users (aka sub-accounts) controlled by the GLAM vault.
20609
+ * These Drift users must share the same user_stats that's also controlled by the GLAM vault.
20610
+ */ async priceDriftUsersIx(priceDenom) {
20611
+ // FIXME: check more users than #0
20612
+ const { user, userStats } = this.drift.getDriftUserPdas();
20613
+ try {
20614
+ const remainingAccounts = await this.drift.composeRemainingAccounts(0);
20615
+ const priceDriftUsersIx = await this.base.program.methods.priceDriftUsers(priceDenom).accounts({
20616
+ glamState: this.base.statePda,
20617
+ solOracle: SOL_ORACLE
20618
+ }).remainingAccounts([
20619
+ {
20620
+ pubkey: userStats,
20621
+ isSigner: false,
20622
+ isWritable: false
20623
+ },
20624
+ {
20625
+ pubkey: user,
20626
+ isSigner: false,
20627
+ isWritable: false
20628
+ },
20629
+ ...remainingAccounts
20630
+ ]).instruction();
20631
+ return priceDriftUsersIx;
20632
+ } catch (error) {
20633
+ return null;
19378
20634
  }
19379
- const tickets = await fetchMarinadeTicketAccounts(this.base.provider.connection, glamVault);
19380
- // @ts-ignore
19381
- const priceTicketsIx = await this.base.program.methods.priceTickets(priceDenom).accounts({
19382
- glamState: this.base.statePda,
19383
- solOracle: SOL_ORACLE
19384
- }).remainingAccounts(tickets.map((t)=>({
19385
- pubkey: t.pubkey,
20635
+ }
20636
+ /**
20637
+ * Returns an instruction that prices a drift vault depositor.
20638
+ * If there are no vault depositor accounts, returns null.
20639
+ */ async priceDriftVaultDepositorsIx(priceDenom) {
20640
+ const parsedVaultDepositors = await this.dvaults.findAndParseVaultDepositors();
20641
+ if (parsedVaultDepositors.length === 0) {
20642
+ return null;
20643
+ }
20644
+ // For each vault deposit, we need the following pubkeys in remaining accounts:
20645
+ // - depositor
20646
+ // - drift vault
20647
+ // - drift user of the vault
20648
+ // - oracles
20649
+ // - spot & perp markets
20650
+ // There might be overlaps between markets and oracles so we use a set to avoid duplicates
20651
+ const remainingAccountsKeys = new Set();
20652
+ for (const depositor of parsedVaultDepositors){
20653
+ remainingAccountsKeys.add(depositor.address.toBase58());
20654
+ remainingAccountsKeys.add(depositor.driftVault.toBase58());
20655
+ const { user: driftUser } = await this.dvaults.parseDriftVault(depositor.driftVault);
20656
+ remainingAccountsKeys.add(driftUser.toBase58());
20657
+ const markets_and_oracles = (await this.dvaults.composeRemainingAccounts(driftUser)).map((a)=>a.pubkey.toBase58());
20658
+ for (const k of markets_and_oracles){
20659
+ remainingAccountsKeys.add(k);
20660
+ }
20661
+ }
20662
+ const remainingAccounts = Array.from(remainingAccountsKeys).map((k)=>({
20663
+ pubkey: new web3_js.PublicKey(k),
19386
20664
  isSigner: false,
19387
20665
  isWritable: false
19388
- }))).instruction();
19389
- const stakes = await fetchStakeAccounts(this.base.provider.connection, glamVault);
20666
+ }));
20667
+ const priceIx = await this.base.program.methods.priceDriftVaultDepositors(priceDenom).accounts({
20668
+ glamState: this.base.statePda,
20669
+ solOracle: SOL_ORACLE
20670
+ }).remainingAccounts(remainingAccounts).instruction();
20671
+ return priceIx;
20672
+ }
20673
+ /**
20674
+ * Returns an instruction that prices vault balance and tokens the vault holds
20675
+ */ async priceVaultIx(priceDenom) {
20676
+ const remainingAccounts = await this.remainingAccountsForPricingVaultAssets(priceDenom == PriceDenom.ASSET);
20677
+ const priceVaultIx = await this.base.program.methods.priceVault(priceDenom).accounts({
20678
+ glamState: this.base.statePda,
20679
+ solOracle: SOL_ORACLE
20680
+ }).remainingAccounts(remainingAccounts).instruction();
20681
+ return priceVaultIx;
20682
+ }
20683
+ /**
20684
+ * Returns an instruction that prices stake accounts.
20685
+ * If there are no stake accounts, returns null.
20686
+ */ async priceStakesIx(priceDenom) {
20687
+ const stakes = await findStakeAccounts(this.base.provider.connection, this.base.vaultPda);
20688
+ if (stakes.length === 0) {
20689
+ return null;
20690
+ }
19390
20691
  const priceStakesIx = await this.base.program.methods.priceStakes(priceDenom).accounts({
19391
20692
  glamState: this.base.statePda,
19392
20693
  solOracle: SOL_ORACLE
19393
- }).remainingAccounts(stakes.map((s)=>({
19394
- pubkey: s,
20694
+ }).remainingAccounts(stakes.map((pubkey)=>({
20695
+ pubkey,
19395
20696
  isSigner: false,
19396
20697
  isWritable: false
19397
20698
  }))).instruction();
20699
+ return priceStakesIx;
20700
+ }
20701
+ /**
20702
+ * Returns an instruction that prices Meteora positions.
20703
+ * If there are no Meteora positions, returns null.
20704
+ */ async priceMeteoraPositionsIx(priceDenom) {
20705
+ const remainingAccounts = await this.remainingAccountsForPricingMeteora();
20706
+ if (remainingAccounts.length === 0) {
20707
+ return null;
20708
+ }
19398
20709
  const priceMeteoraIx = await this.base.program.methods.priceMeteoraPositions(priceDenom).accounts({
19399
20710
  glamState: this.base.statePda,
19400
20711
  solOracle: SOL_ORACLE
19401
- }).remainingAccounts(await this.remainingAccountsForPricingMeteora()).instruction();
19402
- const priceKaminoIx = await this.priceKaminoIx(priceDenom);
19403
- try {
19404
- const { user, userStats } = this.drift.getDriftUserPdas();
19405
- const remainingAccounts = await this.drift.composeRemainingAccounts(0);
19406
- const priceDriftIx = await this.base.program.methods.priceDrift(priceDenom).accounts({
19407
- glamState: this.base.statePda,
19408
- glamVault,
19409
- solOracle: SOL_ORACLE,
19410
- user,
19411
- userStats,
19412
- state: this.drift.driftStatePda
19413
- }).remainingAccounts(remainingAccounts).instruction();
20712
+ }).remainingAccounts(remainingAccounts).instruction();
20713
+ return priceMeteoraIx;
20714
+ }
20715
+ async priceVaultIxs(priceDenom) {
20716
+ const priceVaultIx = await this.priceVaultIx(priceDenom);
20717
+ // If priceDenom is ASSET, only priceVaultIx is returned
20718
+ // We currently don't support pricing other assets in custom base asset
20719
+ // due to the lack of oracles
20720
+ if (priceDenom == PriceDenom.ASSET) {
19414
20721
  return [
19415
- priceTicketsIx,
19416
- priceStakesIx,
19417
- priceVaultIx,
19418
- priceMeteoraIx,
19419
- priceKaminoIx,
19420
- priceDriftIx
20722
+ priceVaultIx
19421
20723
  ];
19422
- } catch (error) {
19423
- // Drift user not found, skip priceDriftIx
20724
+ }
20725
+ // If there are no external assets, we don't need to price DeFi positions
20726
+ const stateModel = await this.base.fetchStateModel();
20727
+ if ((stateModel.externalVaultAccounts || []).length === 0) {
19424
20728
  return [
19425
- priceTicketsIx,
19426
- priceStakesIx,
19427
- priceVaultIx,
19428
- priceMeteoraIx,
19429
- priceKaminoIx
20729
+ priceVaultIx
19430
20730
  ];
19431
20731
  }
19432
- }
19433
- constructor(base, klend, drift){
20732
+ const priceStakesIx = await this.priceStakesIx(priceDenom);
20733
+ const priceMeteoraIx = await this.priceMeteoraPositionsIx(priceDenom);
20734
+ const priceKaminoIx = await this.priceKaminoObligationsIx(priceDenom);
20735
+ const priceDriftUsersIx = await this.priceDriftUsersIx(priceDenom);
20736
+ const priceDriftVaultDepositorsIx = await this.priceDriftVaultDepositorsIx(priceDenom);
20737
+ return [
20738
+ priceVaultIx,
20739
+ priceStakesIx,
20740
+ priceMeteoraIx,
20741
+ priceKaminoIx,
20742
+ priceDriftUsersIx,
20743
+ priceDriftVaultDepositorsIx
20744
+ ].filter((ix)=>ix !== null);
20745
+ }
20746
+ constructor(base, klend, kvaults, drift, dvaults){
19434
20747
  this.base = base;
19435
20748
  this.klend = klend;
20749
+ this.kvaults = kvaults;
19436
20750
  this.drift = drift;
20751
+ this.dvaults = dvaults;
19437
20752
  this.remainingAccountsForPricingMeteora = async ()=>{
19438
- const glamVault = this.base.vaultPda;
19439
- const positions = await fetchMeteoraPositions(this.base.provider.connection, glamVault);
20753
+ const positions = await fetchMeteoraPositions(this.base.provider.connection, this.base.vaultPda);
19440
20754
  let chunks = await Promise.all(positions.map(async (pubkey)=>{
19441
20755
  const { lbPair, binArrayLower, binArrayUpper } = await parseMeteoraPosition(this.base.provider.connection, pubkey);
19442
20756
  return [
@@ -19444,8 +20758,8 @@ class PriceClient {
19444
20758
  lbPair,
19445
20759
  binArrayLower,
19446
20760
  binArrayUpper,
19447
- new web3_js.PublicKey("3m6i4RFWEDw2Ft4tFHPJtYgmpPe21k56M3FHeWYrgGBz"),
19448
- new web3_js.PublicKey("9VCioxmni2gDLv11qufWzT3RDERhQE4iY5Gf7NTfYyAV")
20761
+ SOL_ORACLE,
20762
+ USDC_ORACLE
19449
20763
  ].map((k)=>({
19450
20764
  pubkey: k,
19451
20765
  isSigner: false,
@@ -19505,6 +20819,12 @@ class PriceClient {
19505
20819
  }
19506
20820
  return this._drift;
19507
20821
  }
20822
+ get driftVaults() {
20823
+ if (!this._driftVaults) {
20824
+ this._driftVaults = new DriftVaultsClient(this, this.drift);
20825
+ }
20826
+ return this._driftVaults;
20827
+ }
19508
20828
  get investor() {
19509
20829
  if (!this._investor) {
19510
20830
  this._investor = new InvestorClient(this);
@@ -19543,7 +20863,7 @@ class PriceClient {
19543
20863
  }
19544
20864
  get price() {
19545
20865
  if (!this._price) {
19546
- this._price = new PriceClient(this, this.kaminoLending, this.drift);
20866
+ this._price = new PriceClient(this, this.kaminoLending, this.kaminoVaults, this.drift, this.driftVaults);
19547
20867
  }
19548
20868
  return this._price;
19549
20869
  }
@@ -19571,6 +20891,12 @@ class PriceClient {
19571
20891
  }
19572
20892
  return this._kaminoFarm;
19573
20893
  }
20894
+ get kaminoVaults() {
20895
+ if (!this._kaminoVaults) {
20896
+ this._kaminoVaults = new KaminoVaultsClient(this, this.kaminoLending);
20897
+ }
20898
+ return this._kaminoVaults;
20899
+ }
19574
20900
  get meteoraDlmm() {
19575
20901
  if (!this._meteoraDlmm) {
19576
20902
  this._meteoraDlmm = new MeteoraDlmmClient(this);
@@ -19663,11 +20989,14 @@ exports.ContractTier = ContractTier;
19663
20989
  exports.ContractType = ContractType;
19664
20990
  exports.CreatedModel = CreatedModel;
19665
20991
  exports.DRIFT_PROGRAM_ID = DRIFT_PROGRAM_ID;
20992
+ exports.DRIFT_VAULTS_PROGRAM_ID = DRIFT_VAULTS_PROGRAM_ID;
20993
+ exports.DRIFT_VAULT_DEPOSITOR_SIZE = DRIFT_VAULT_DEPOSITOR_SIZE;
19666
20994
  exports.DefaultOrderParams = DefaultOrderParams;
19667
20995
  exports.DelegateAcl = DelegateAcl;
19668
20996
  exports.DepositDirection = DepositDirection;
19669
20997
  exports.DepositExplanation = DepositExplanation;
19670
20998
  exports.DriftClient = DriftClient;
20999
+ exports.DriftVaultsClient = DriftVaultsClient;
19671
21000
  exports.ExchangeStatus = ExchangeStatus;
19672
21001
  exports.FuelOverflowStatus = FuelOverflowStatus;
19673
21002
  exports.FundOpenfundsModel = FundOpenfundsModel;
@@ -19693,11 +21022,11 @@ exports.KAMINO_FARM_PROGRAM = KAMINO_FARM_PROGRAM;
19693
21022
  exports.KAMINO_LENDING_PROGRAM = KAMINO_LENDING_PROGRAM;
19694
21023
  exports.KAMINO_OBTRIGATION_SIZE = KAMINO_OBTRIGATION_SIZE;
19695
21024
  exports.KAMINO_SCOPE_PRICES = KAMINO_SCOPE_PRICES;
21025
+ exports.KAMINO_VAULTS_PROGRAM = KAMINO_VAULTS_PROGRAM;
19696
21026
  exports.LPAction = LPAction;
19697
21027
  exports.LiquidationType = LiquidationType;
19698
21028
  exports.MARINADE_NATIVE_STAKE_AUTHORITY = MARINADE_NATIVE_STAKE_AUTHORITY;
19699
21029
  exports.MARINADE_PROGRAM_ID = MARINADE_PROGRAM_ID;
19700
- exports.MARINADE_TICKET_SIZE = MARINADE_TICKET_SIZE;
19701
21030
  exports.MEMO_PROGRAM = MEMO_PROGRAM;
19702
21031
  exports.MERKLE_DISTRIBUTOR_PROGRAM = MERKLE_DISTRIBUTOR_PROGRAM;
19703
21032
  exports.METEORA_DLMM_PROGRAM = METEORA_DLMM_PROGRAM;
@@ -19751,15 +21080,14 @@ exports.TRANSFER_HOOK_PROGRAM = TRANSFER_HOOK_PROGRAM;
19751
21080
  exports.TimeUnit = TimeUnit;
19752
21081
  exports.TradeSide = TradeSide;
19753
21082
  exports.USDC = USDC;
21083
+ exports.USDC_ORACLE = USDC_ORACLE;
19754
21084
  exports.UserStatus = UserStatus;
19755
21085
  exports.WSOL = WSOL;
19756
21086
  exports.ZERO = ZERO;
19757
21087
  exports.decodeUser = decodeUser;
19758
- exports.fetchKaminoObligations = fetchKaminoObligations;
19759
21088
  exports.fetchLookupTables = fetchLookupTables;
19760
- exports.fetchMarinadeTicketAccounts = fetchMarinadeTicketAccounts;
19761
21089
  exports.fetchMeteoraPositions = fetchMeteoraPositions;
19762
- exports.fetchStakeAccounts = fetchStakeAccounts;
21090
+ exports.findStakeAccounts = findStakeAccounts;
19763
21091
  exports.getAccountPolicyPda = getAccountPolicyPda;
19764
21092
  exports.getEscrowPda = getEscrowPda;
19765
21093
  exports.getExtraMetasPda = getExtraMetasPda;
@@ -19782,4 +21110,5 @@ exports.isBrowser = isBrowser;
19782
21110
  exports.isOneOfVariant = isOneOfVariant;
19783
21111
  exports.isVariant = isVariant;
19784
21112
  exports.parseMeteoraPosition = parseMeteoraPosition;
21113
+ exports.parseProgramLogs = parseProgramLogs;
19785
21114
  exports.setsAreEqual = setsAreEqual;