@lightprotocol/compressed-token 0.16.0 → 0.17.1
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/dist/cjs/browser/index.cjs +440 -706
- package/dist/cjs/browser/index.cjs.map +1 -1
- package/dist/cjs/node/index.cjs +440 -706
- package/dist/cjs/node/index.cjs.map +1 -1
- package/dist/es/browser/index.js +405 -635
- package/dist/es/browser/index.js.map +1 -1
- package/dist/types/index.d.ts +274 -279
- package/package.json +2 -2
package/dist/es/browser/index.js
CHANGED
|
@@ -1,36 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
bn,
|
|
4
|
-
padOutputStateMerkleTrees,
|
|
5
|
-
useWallet,
|
|
6
|
-
confirmConfig,
|
|
7
|
-
defaultStaticAccountsStruct,
|
|
8
|
-
toArray,
|
|
9
|
-
LightSystemProgram,
|
|
10
|
-
defaultTestStateTreeAccounts,
|
|
11
|
-
sumUpLamports,
|
|
12
|
-
validateSufficientBalance,
|
|
13
|
-
validateSameOwner,
|
|
14
|
-
dedupeSigner,
|
|
15
|
-
buildAndSignTx,
|
|
16
|
-
sendAndConfirmTx,
|
|
17
|
-
} from '@lightprotocol/stateless.js';
|
|
18
|
-
import {
|
|
19
|
-
PublicKey,
|
|
20
|
-
Keypair,
|
|
21
|
-
Connection,
|
|
22
|
-
SystemProgram,
|
|
23
|
-
AddressLookupTableProgram,
|
|
24
|
-
ComputeBudgetProgram,
|
|
25
|
-
} from '@solana/web3.js';
|
|
1
|
+
import { getIndexOrAdd, bn, padOutputStateMerkleTrees, useWallet, confirmConfig, defaultStaticAccountsStruct, toArray, LightSystemProgram, defaultTestStateTreeAccounts, sumUpLamports, validateSufficientBalance, validateSameOwner, dedupeSigner, buildAndSignTx, sendAndConfirmTx } from '@lightprotocol/stateless.js';
|
|
2
|
+
import { PublicKey, Keypair, Connection, SystemProgram, AddressLookupTableProgram, ComputeBudgetProgram } from '@solana/web3.js';
|
|
26
3
|
import { AnchorProvider, setProvider, Program, BN } from '@coral-xyz/anchor';
|
|
27
|
-
import {
|
|
28
|
-
TOKEN_PROGRAM_ID,
|
|
29
|
-
MINT_SIZE,
|
|
30
|
-
createInitializeMint2Instruction,
|
|
31
|
-
createMintToInstruction,
|
|
32
|
-
getOrCreateAssociatedTokenAccount,
|
|
33
|
-
} from '@solana/spl-token';
|
|
4
|
+
import { MINT_SIZE, createInitializeMint2Instruction, createMintToInstruction, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, getOrCreateAssociatedTokenAccount } from '@solana/spl-token';
|
|
34
5
|
|
|
35
6
|
const IDL = {
|
|
36
7
|
version: '1.2.0',
|
|
@@ -116,9 +87,6 @@ const IDL = {
|
|
|
116
87
|
name: 'tokenPoolPda',
|
|
117
88
|
isMut: true,
|
|
118
89
|
isSigner: false,
|
|
119
|
-
docs: [
|
|
120
|
-
'account to a token account of a different mint will fail',
|
|
121
|
-
],
|
|
122
90
|
},
|
|
123
91
|
{
|
|
124
92
|
name: 'tokenProgram',
|
|
@@ -196,6 +164,11 @@ const IDL = {
|
|
|
196
164
|
},
|
|
197
165
|
{
|
|
198
166
|
name: 'compressSplTokenAccount',
|
|
167
|
+
docs: [
|
|
168
|
+
'Compresses the balance of an spl token account sub an optional remaining',
|
|
169
|
+
'amount. This instruction does not close the spl token account. To close',
|
|
170
|
+
'the account bundle a close spl account instruction in your transaction.',
|
|
171
|
+
],
|
|
199
172
|
accounts: [
|
|
200
173
|
{
|
|
201
174
|
name: 'feePayer',
|
|
@@ -1189,8 +1162,7 @@ const IDL = {
|
|
|
1189
1162
|
name: 'inputCompressedAccountsWithMerkleContext',
|
|
1190
1163
|
type: {
|
|
1191
1164
|
vec: {
|
|
1192
|
-
defined:
|
|
1193
|
-
'PackedCompressedAccountWithMerkleContext',
|
|
1165
|
+
defined: 'PackedCompressedAccountWithMerkleContext',
|
|
1194
1166
|
},
|
|
1195
1167
|
},
|
|
1196
1168
|
},
|
|
@@ -1198,8 +1170,7 @@ const IDL = {
|
|
|
1198
1170
|
name: 'outputCompressedAccounts',
|
|
1199
1171
|
type: {
|
|
1200
1172
|
vec: {
|
|
1201
|
-
defined:
|
|
1202
|
-
'OutputCompressedAccountWithPackedContext',
|
|
1173
|
+
defined: 'OutputCompressedAccountWithPackedContext',
|
|
1203
1174
|
},
|
|
1204
1175
|
},
|
|
1205
1176
|
},
|
|
@@ -1255,8 +1226,7 @@ const IDL = {
|
|
|
1255
1226
|
name: 'inputCompressedAccountsWithMerkleContext',
|
|
1256
1227
|
type: {
|
|
1257
1228
|
vec: {
|
|
1258
|
-
defined:
|
|
1259
|
-
'PackedCompressedAccountWithMerkleContext',
|
|
1229
|
+
defined: 'PackedCompressedAccountWithMerkleContext',
|
|
1260
1230
|
},
|
|
1261
1231
|
},
|
|
1262
1232
|
},
|
|
@@ -1264,8 +1234,7 @@ const IDL = {
|
|
|
1264
1234
|
name: 'outputCompressedAccounts',
|
|
1265
1235
|
type: {
|
|
1266
1236
|
vec: {
|
|
1267
|
-
defined:
|
|
1268
|
-
'OutputCompressedAccountWithPackedContext',
|
|
1237
|
+
defined: 'OutputCompressedAccountWithPackedContext',
|
|
1269
1238
|
},
|
|
1270
1239
|
},
|
|
1271
1240
|
},
|
|
@@ -1510,8 +1479,7 @@ const IDL = {
|
|
|
1510
1479
|
name: 'outputCompressedAccounts',
|
|
1511
1480
|
type: {
|
|
1512
1481
|
vec: {
|
|
1513
|
-
defined:
|
|
1514
|
-
'OutputCompressedAccountWithPackedContext',
|
|
1482
|
+
defined: 'OutputCompressedAccountWithPackedContext',
|
|
1515
1483
|
},
|
|
1516
1484
|
},
|
|
1517
1485
|
},
|
|
@@ -1688,23 +1656,141 @@ const IDL = {
|
|
|
1688
1656
|
errors: [
|
|
1689
1657
|
{
|
|
1690
1658
|
code: 6000,
|
|
1691
|
-
name: '
|
|
1692
|
-
msg: '
|
|
1659
|
+
name: 'PublicKeyAmountMissmatch',
|
|
1660
|
+
msg: 'public keys and amounts must be of same length',
|
|
1693
1661
|
},
|
|
1694
1662
|
{
|
|
1695
1663
|
code: 6001,
|
|
1696
|
-
name: '
|
|
1697
|
-
msg: '
|
|
1664
|
+
name: 'ComputeInputSumFailed',
|
|
1665
|
+
msg: 'ComputeInputSumFailed',
|
|
1698
1666
|
},
|
|
1699
1667
|
{
|
|
1700
1668
|
code: 6002,
|
|
1701
|
-
name: '
|
|
1702
|
-
msg: '
|
|
1669
|
+
name: 'ComputeOutputSumFailed',
|
|
1670
|
+
msg: 'ComputeOutputSumFailed',
|
|
1703
1671
|
},
|
|
1704
1672
|
{
|
|
1705
1673
|
code: 6003,
|
|
1706
|
-
name: '
|
|
1707
|
-
msg: '
|
|
1674
|
+
name: 'ComputeCompressSumFailed',
|
|
1675
|
+
msg: 'ComputeCompressSumFailed',
|
|
1676
|
+
},
|
|
1677
|
+
{
|
|
1678
|
+
code: 6004,
|
|
1679
|
+
name: 'ComputeDecompressSumFailed',
|
|
1680
|
+
msg: 'ComputeDecompressSumFailed',
|
|
1681
|
+
},
|
|
1682
|
+
{
|
|
1683
|
+
code: 6005,
|
|
1684
|
+
name: 'SumCheckFailed',
|
|
1685
|
+
msg: 'SumCheckFailed',
|
|
1686
|
+
},
|
|
1687
|
+
{
|
|
1688
|
+
code: 6006,
|
|
1689
|
+
name: 'DecompressRecipientUndefinedForDecompress',
|
|
1690
|
+
msg: 'DecompressRecipientUndefinedForDecompress',
|
|
1691
|
+
},
|
|
1692
|
+
{
|
|
1693
|
+
code: 6007,
|
|
1694
|
+
name: 'CompressedPdaUndefinedForDecompress',
|
|
1695
|
+
msg: 'CompressedPdaUndefinedForDecompress',
|
|
1696
|
+
},
|
|
1697
|
+
{
|
|
1698
|
+
code: 6008,
|
|
1699
|
+
name: 'DeCompressAmountUndefinedForDecompress',
|
|
1700
|
+
msg: 'DeCompressAmountUndefinedForDecompress',
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
code: 6009,
|
|
1704
|
+
name: 'CompressedPdaUndefinedForCompress',
|
|
1705
|
+
msg: 'CompressedPdaUndefinedForCompress',
|
|
1706
|
+
},
|
|
1707
|
+
{
|
|
1708
|
+
code: 6010,
|
|
1709
|
+
name: 'DeCompressAmountUndefinedForCompress',
|
|
1710
|
+
msg: 'DeCompressAmountUndefinedForCompress',
|
|
1711
|
+
},
|
|
1712
|
+
{
|
|
1713
|
+
code: 6011,
|
|
1714
|
+
name: 'DelegateSignerCheckFailed',
|
|
1715
|
+
msg: 'DelegateSignerCheckFailed',
|
|
1716
|
+
},
|
|
1717
|
+
{
|
|
1718
|
+
code: 6012,
|
|
1719
|
+
name: 'MintTooLarge',
|
|
1720
|
+
msg: 'Minted amount greater than u64::MAX',
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
code: 6013,
|
|
1724
|
+
name: 'SplTokenSupplyMismatch',
|
|
1725
|
+
msg: 'SplTokenSupplyMismatch',
|
|
1726
|
+
},
|
|
1727
|
+
{
|
|
1728
|
+
code: 6014,
|
|
1729
|
+
name: 'HeapMemoryCheckFailed',
|
|
1730
|
+
msg: 'HeapMemoryCheckFailed',
|
|
1731
|
+
},
|
|
1732
|
+
{
|
|
1733
|
+
code: 6015,
|
|
1734
|
+
name: 'InstructionNotCallable',
|
|
1735
|
+
msg: 'The instruction is not callable',
|
|
1736
|
+
},
|
|
1737
|
+
{
|
|
1738
|
+
code: 6016,
|
|
1739
|
+
name: 'ArithmeticUnderflow',
|
|
1740
|
+
msg: 'ArithmeticUnderflow',
|
|
1741
|
+
},
|
|
1742
|
+
{
|
|
1743
|
+
code: 6017,
|
|
1744
|
+
name: 'HashToFieldError',
|
|
1745
|
+
msg: 'HashToFieldError',
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1748
|
+
code: 6018,
|
|
1749
|
+
name: 'InvalidAuthorityMint',
|
|
1750
|
+
msg: 'Expected the authority to be also a mint authority',
|
|
1751
|
+
},
|
|
1752
|
+
{
|
|
1753
|
+
code: 6019,
|
|
1754
|
+
name: 'InvalidFreezeAuthority',
|
|
1755
|
+
msg: 'Provided authority is not the freeze authority',
|
|
1756
|
+
},
|
|
1757
|
+
{
|
|
1758
|
+
code: 6020,
|
|
1759
|
+
name: 'InvalidDelegateIndex',
|
|
1760
|
+
},
|
|
1761
|
+
{
|
|
1762
|
+
code: 6021,
|
|
1763
|
+
name: 'TokenPoolPdaUndefined',
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
code: 6022,
|
|
1767
|
+
name: 'IsTokenPoolPda',
|
|
1768
|
+
msg: 'Compress or decompress recipient is the same account as the token pool pda.',
|
|
1769
|
+
},
|
|
1770
|
+
{
|
|
1771
|
+
code: 6023,
|
|
1772
|
+
name: 'InvalidTokenPoolPda',
|
|
1773
|
+
},
|
|
1774
|
+
{
|
|
1775
|
+
code: 6024,
|
|
1776
|
+
name: 'NoInputTokenAccountsProvided',
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
code: 6025,
|
|
1780
|
+
name: 'NoInputsProvided',
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
code: 6026,
|
|
1784
|
+
name: 'MintHasNoFreezeAuthority',
|
|
1785
|
+
},
|
|
1786
|
+
{
|
|
1787
|
+
code: 6027,
|
|
1788
|
+
name: 'MintWithInvalidExtension',
|
|
1789
|
+
},
|
|
1790
|
+
{
|
|
1791
|
+
code: 6028,
|
|
1792
|
+
name: 'InsufficientTokenAccountBalance',
|
|
1793
|
+
msg: 'The token account balance is less than the remaining amount.',
|
|
1708
1794
|
},
|
|
1709
1795
|
],
|
|
1710
1796
|
};
|
|
@@ -1714,37 +1800,20 @@ const IDL = {
|
|
|
1714
1800
|
* Packs Compressed Token Accounts.
|
|
1715
1801
|
*/
|
|
1716
1802
|
function packCompressedTokenAccounts(params) {
|
|
1717
|
-
const {
|
|
1718
|
-
inputCompressedTokenAccounts,
|
|
1719
|
-
outputStateTrees,
|
|
1720
|
-
remainingAccounts = [],
|
|
1721
|
-
rootIndices,
|
|
1722
|
-
tokenTransferOutputs,
|
|
1723
|
-
} = params;
|
|
1803
|
+
const { inputCompressedTokenAccounts, outputStateTrees, remainingAccounts = [], rootIndices, tokenTransferOutputs, } = params;
|
|
1724
1804
|
const _remainingAccounts = remainingAccounts.slice();
|
|
1725
1805
|
let delegateIndex = null;
|
|
1726
|
-
if (
|
|
1727
|
-
inputCompressedTokenAccounts.
|
|
1728
|
-
inputCompressedTokenAccounts[0].parsed.delegate
|
|
1729
|
-
) {
|
|
1730
|
-
delegateIndex = getIndexOrAdd(
|
|
1731
|
-
_remainingAccounts,
|
|
1732
|
-
inputCompressedTokenAccounts[0].parsed.delegate,
|
|
1733
|
-
);
|
|
1806
|
+
if (inputCompressedTokenAccounts.length > 0 &&
|
|
1807
|
+
inputCompressedTokenAccounts[0].parsed.delegate) {
|
|
1808
|
+
delegateIndex = getIndexOrAdd(_remainingAccounts, inputCompressedTokenAccounts[0].parsed.delegate);
|
|
1734
1809
|
}
|
|
1735
1810
|
/// TODO: move pubkeyArray to remainingAccounts
|
|
1736
1811
|
/// Currently just packs 'delegate' to pubkeyArray
|
|
1737
1812
|
const packedInputTokenData = [];
|
|
1738
1813
|
/// pack inputs
|
|
1739
1814
|
inputCompressedTokenAccounts.forEach((account, index) => {
|
|
1740
|
-
const merkleTreePubkeyIndex = getIndexOrAdd(
|
|
1741
|
-
|
|
1742
|
-
account.compressedAccount.merkleTree,
|
|
1743
|
-
);
|
|
1744
|
-
const nullifierQueuePubkeyIndex = getIndexOrAdd(
|
|
1745
|
-
_remainingAccounts,
|
|
1746
|
-
account.compressedAccount.nullifierQueue,
|
|
1747
|
-
);
|
|
1815
|
+
const merkleTreePubkeyIndex = getIndexOrAdd(_remainingAccounts, account.compressedAccount.merkleTree);
|
|
1816
|
+
const nullifierQueuePubkeyIndex = getIndexOrAdd(_remainingAccounts, account.compressedAccount.nullifierQueue);
|
|
1748
1817
|
packedInputTokenData.push({
|
|
1749
1818
|
amount: account.parsed.amount,
|
|
1750
1819
|
delegateIndex,
|
|
@@ -1762,11 +1831,7 @@ function packCompressedTokenAccounts(params) {
|
|
|
1762
1831
|
});
|
|
1763
1832
|
});
|
|
1764
1833
|
/// pack output state trees
|
|
1765
|
-
const paddedOutputStateMerkleTrees = padOutputStateMerkleTrees(
|
|
1766
|
-
outputStateTrees,
|
|
1767
|
-
tokenTransferOutputs.length,
|
|
1768
|
-
inputCompressedTokenAccounts.map(acc => acc.compressedAccount),
|
|
1769
|
-
);
|
|
1834
|
+
const paddedOutputStateMerkleTrees = padOutputStateMerkleTrees(outputStateTrees, tokenTransferOutputs.length, inputCompressedTokenAccounts.map(acc => acc.compressedAccount));
|
|
1770
1835
|
const packedOutputTokenData = [];
|
|
1771
1836
|
paddedOutputStateMerkleTrees.forEach((account, index) => {
|
|
1772
1837
|
const merkleTreeIndex = getIndexOrAdd(_remainingAccounts, account);
|
|
@@ -1781,7 +1846,7 @@ function packCompressedTokenAccounts(params) {
|
|
|
1781
1846
|
});
|
|
1782
1847
|
});
|
|
1783
1848
|
// to meta
|
|
1784
|
-
const remainingAccountMetas = _remainingAccounts.map(account => ({
|
|
1849
|
+
const remainingAccountMetas = _remainingAccounts.map((account) => ({
|
|
1785
1850
|
pubkey: account,
|
|
1786
1851
|
isWritable: true,
|
|
1787
1852
|
isSigner: false,
|
|
@@ -1800,16 +1865,13 @@ const SPL_TOKEN_MINT_RENT_EXEMPT_BALANCE = 1461600;
|
|
|
1800
1865
|
/**
|
|
1801
1866
|
* Sum up the token amounts of the compressed token accounts
|
|
1802
1867
|
*/
|
|
1803
|
-
const sumUpTokenAmount = accounts => {
|
|
1804
|
-
return accounts.reduce(
|
|
1805
|
-
(acc, account) => acc.add(account.parsed.amount),
|
|
1806
|
-
bn(0),
|
|
1807
|
-
);
|
|
1868
|
+
const sumUpTokenAmount = (accounts) => {
|
|
1869
|
+
return accounts.reduce((acc, account) => acc.add(account.parsed.amount), bn(0));
|
|
1808
1870
|
};
|
|
1809
1871
|
/**
|
|
1810
1872
|
* Validate that all the compressed token accounts are owned by the same owner.
|
|
1811
1873
|
*/
|
|
1812
|
-
const validateSameTokenOwner = accounts => {
|
|
1874
|
+
const validateSameTokenOwner = (accounts) => {
|
|
1813
1875
|
const owner = accounts[0].parsed.owner;
|
|
1814
1876
|
accounts.forEach(acc => {
|
|
1815
1877
|
if (!acc.parsed.owner.equals(owner)) {
|
|
@@ -1820,7 +1882,7 @@ const validateSameTokenOwner = accounts => {
|
|
|
1820
1882
|
/**
|
|
1821
1883
|
* Parse compressed token accounts to get the mint, current owner and delegate.
|
|
1822
1884
|
*/
|
|
1823
|
-
const parseTokenData = compressedTokenAccounts => {
|
|
1885
|
+
const parseTokenData = (compressedTokenAccounts) => {
|
|
1824
1886
|
const mint = compressedTokenAccounts[0].parsed.mint;
|
|
1825
1887
|
const currentOwner = compressedTokenAccounts[0].parsed.owner;
|
|
1826
1888
|
const delegate = compressedTokenAccounts[0].parsed.delegate;
|
|
@@ -1834,16 +1896,10 @@ const parseTokenData = compressedTokenAccounts => {
|
|
|
1834
1896
|
* @returns Output token data for the transfer
|
|
1835
1897
|
* instruction
|
|
1836
1898
|
*/
|
|
1837
|
-
function createTransferOutputState(
|
|
1838
|
-
inputCompressedTokenAccounts,
|
|
1839
|
-
toAddress,
|
|
1840
|
-
amount,
|
|
1841
|
-
) {
|
|
1899
|
+
function createTransferOutputState(inputCompressedTokenAccounts, toAddress, amount) {
|
|
1842
1900
|
amount = bn(amount);
|
|
1843
1901
|
const inputAmount = sumUpTokenAmount(inputCompressedTokenAccounts);
|
|
1844
|
-
const inputLamports = sumUpLamports(
|
|
1845
|
-
inputCompressedTokenAccounts.map(acc => acc.compressedAccount),
|
|
1846
|
-
);
|
|
1902
|
+
const inputLamports = sumUpLamports(inputCompressedTokenAccounts.map(acc => acc.compressedAccount));
|
|
1847
1903
|
const changeAmount = inputAmount.sub(amount);
|
|
1848
1904
|
validateSufficientBalance(changeAmount);
|
|
1849
1905
|
if (changeAmount.eq(bn(0)) && inputLamports.eq(bn(0))) {
|
|
@@ -1857,9 +1913,7 @@ function createTransferOutputState(
|
|
|
1857
1913
|
];
|
|
1858
1914
|
}
|
|
1859
1915
|
/// validates token program
|
|
1860
|
-
validateSameOwner(
|
|
1861
|
-
inputCompressedTokenAccounts.map(acc => acc.compressedAccount),
|
|
1862
|
-
);
|
|
1916
|
+
validateSameOwner(inputCompressedTokenAccounts.map(acc => acc.compressedAccount));
|
|
1863
1917
|
validateSameTokenOwner(inputCompressedTokenAccounts);
|
|
1864
1918
|
const outputCompressedAccounts = [
|
|
1865
1919
|
{
|
|
@@ -1886,9 +1940,7 @@ function createTransferOutputState(
|
|
|
1886
1940
|
*/
|
|
1887
1941
|
function createDecompressOutputState(inputCompressedTokenAccounts, amount) {
|
|
1888
1942
|
amount = bn(amount);
|
|
1889
|
-
const inputLamports = sumUpLamports(
|
|
1890
|
-
inputCompressedTokenAccounts.map(acc => acc.compressedAccount),
|
|
1891
|
-
);
|
|
1943
|
+
const inputLamports = sumUpLamports(inputCompressedTokenAccounts.map(acc => acc.compressedAccount));
|
|
1892
1944
|
const inputAmount = sumUpTokenAmount(inputCompressedTokenAccounts);
|
|
1893
1945
|
const changeAmount = inputAmount.sub(amount);
|
|
1894
1946
|
validateSufficientBalance(changeAmount);
|
|
@@ -1896,9 +1948,7 @@ function createDecompressOutputState(inputCompressedTokenAccounts, amount) {
|
|
|
1896
1948
|
if (changeAmount.eq(bn(0)) && inputLamports.eq(bn(0))) {
|
|
1897
1949
|
return [];
|
|
1898
1950
|
}
|
|
1899
|
-
validateSameOwner(
|
|
1900
|
-
inputCompressedTokenAccounts.map(acc => acc.compressedAccount),
|
|
1901
|
-
);
|
|
1951
|
+
validateSameOwner(inputCompressedTokenAccounts.map(acc => acc.compressedAccount));
|
|
1902
1952
|
validateSameTokenOwner(inputCompressedTokenAccounts);
|
|
1903
1953
|
const tokenTransferOutputs = [
|
|
1904
1954
|
{
|
|
@@ -1914,13 +1964,11 @@ class CompressedTokenProgram {
|
|
|
1914
1964
|
/**
|
|
1915
1965
|
* @internal
|
|
1916
1966
|
*/
|
|
1917
|
-
constructor() {}
|
|
1967
|
+
constructor() { }
|
|
1918
1968
|
/**
|
|
1919
1969
|
* Public key that identifies the CompressedPda program
|
|
1920
1970
|
*/
|
|
1921
|
-
static programId = new PublicKey(
|
|
1922
|
-
'cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m',
|
|
1923
|
-
);
|
|
1971
|
+
static programId = new PublicKey('cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m');
|
|
1924
1972
|
/**
|
|
1925
1973
|
* Set a custom programId via PublicKey or base58 encoded string.
|
|
1926
1974
|
* This method is not required for regular usage.
|
|
@@ -1953,15 +2001,8 @@ class CompressedTokenProgram {
|
|
|
1953
2001
|
/// program only for serde and building instructions, not for
|
|
1954
2002
|
/// interacting with the network.
|
|
1955
2003
|
const mockKeypair = Keypair.generate();
|
|
1956
|
-
const mockConnection = new Connection(
|
|
1957
|
-
|
|
1958
|
-
'confirmed',
|
|
1959
|
-
);
|
|
1960
|
-
const mockProvider = new AnchorProvider(
|
|
1961
|
-
mockConnection,
|
|
1962
|
-
useWallet(mockKeypair),
|
|
1963
|
-
confirmConfig,
|
|
1964
|
-
);
|
|
2004
|
+
const mockConnection = new Connection('http://127.0.0.1:8899', 'confirmed');
|
|
2005
|
+
const mockProvider = new AnchorProvider(mockConnection, useWallet(mockKeypair), confirmConfig);
|
|
1965
2006
|
setProvider(mockProvider);
|
|
1966
2007
|
this._program = new Program(IDL, this.programId, mockProvider);
|
|
1967
2008
|
}
|
|
@@ -1969,63 +2010,61 @@ class CompressedTokenProgram {
|
|
|
1969
2010
|
/** @internal */
|
|
1970
2011
|
static deriveTokenPoolPda(mint) {
|
|
1971
2012
|
const seeds = [POOL_SEED, mint.toBuffer()];
|
|
1972
|
-
const [address, _] = PublicKey.findProgramAddressSync(
|
|
1973
|
-
seeds,
|
|
1974
|
-
this.programId,
|
|
1975
|
-
);
|
|
2013
|
+
const [address, _] = PublicKey.findProgramAddressSync(seeds, this.programId);
|
|
1976
2014
|
return address;
|
|
1977
2015
|
}
|
|
1978
2016
|
/** @internal */
|
|
1979
2017
|
static get deriveCpiAuthorityPda() {
|
|
1980
|
-
const [address, _] = PublicKey.findProgramAddressSync(
|
|
1981
|
-
[CPI_AUTHORITY_SEED],
|
|
1982
|
-
this.programId,
|
|
1983
|
-
);
|
|
2018
|
+
const [address, _] = PublicKey.findProgramAddressSync([CPI_AUTHORITY_SEED], this.programId);
|
|
1984
2019
|
return address;
|
|
1985
2020
|
}
|
|
1986
2021
|
/**
|
|
1987
|
-
* Construct createMint instruction for compressed tokens
|
|
2022
|
+
* Construct createMint instruction for compressed tokens.
|
|
2023
|
+
* @returns [createMintAccountInstruction, initializeMintInstruction, createTokenPoolInstruction]
|
|
2024
|
+
*
|
|
2025
|
+
* Note that `createTokenPoolInstruction` must be executed after `initializeMintInstruction`.
|
|
1988
2026
|
*/
|
|
1989
2027
|
static async createMint(params) {
|
|
1990
|
-
const { mint, authority, feePayer, rentExemptBalance } = params;
|
|
2028
|
+
const { mint, authority, feePayer, rentExemptBalance, tokenProgramId, freezeAuthority, mintSize, } = params;
|
|
2029
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
1991
2030
|
/// Create and initialize SPL Mint account
|
|
1992
2031
|
const createMintAccountInstruction = SystemProgram.createAccount({
|
|
1993
2032
|
fromPubkey: feePayer,
|
|
1994
2033
|
lamports: rentExemptBalance,
|
|
1995
2034
|
newAccountPubkey: mint,
|
|
1996
|
-
programId:
|
|
1997
|
-
space: MINT_SIZE,
|
|
2035
|
+
programId: tokenProgram,
|
|
2036
|
+
space: mintSize ?? MINT_SIZE,
|
|
1998
2037
|
});
|
|
1999
|
-
const initializeMintInstruction = createInitializeMint2Instruction(
|
|
2000
|
-
|
|
2001
|
-
params.decimals,
|
|
2002
|
-
authority,
|
|
2003
|
-
params.freezeAuthority,
|
|
2004
|
-
TOKEN_PROGRAM_ID,
|
|
2005
|
-
);
|
|
2006
|
-
const ix = await this.createTokenPool({
|
|
2038
|
+
const initializeMintInstruction = createInitializeMint2Instruction(mint, params.decimals, authority, freezeAuthority, tokenProgram);
|
|
2039
|
+
const createTokenPoolInstruction = await this.createTokenPool({
|
|
2007
2040
|
feePayer,
|
|
2008
2041
|
mint,
|
|
2042
|
+
tokenProgramId: tokenProgram,
|
|
2009
2043
|
});
|
|
2010
|
-
return [
|
|
2044
|
+
return [
|
|
2045
|
+
createMintAccountInstruction,
|
|
2046
|
+
initializeMintInstruction,
|
|
2047
|
+
createTokenPoolInstruction,
|
|
2048
|
+
];
|
|
2011
2049
|
}
|
|
2012
2050
|
/**
|
|
2013
2051
|
* Enable compression for an existing SPL mint, creating an omnibus account.
|
|
2014
2052
|
* For new mints, use `CompressedTokenProgram.createMint`.
|
|
2015
2053
|
*/
|
|
2016
2054
|
static async createTokenPool(params) {
|
|
2017
|
-
const { mint, feePayer } = params;
|
|
2055
|
+
const { mint, feePayer, tokenProgramId } = params;
|
|
2056
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2018
2057
|
const tokenPoolPda = this.deriveTokenPoolPda(mint);
|
|
2019
2058
|
const ix = await this.program.methods
|
|
2020
2059
|
.createTokenPool()
|
|
2021
2060
|
.accounts({
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2061
|
+
mint,
|
|
2062
|
+
feePayer,
|
|
2063
|
+
tokenPoolPda,
|
|
2064
|
+
systemProgram: SystemProgram.programId,
|
|
2065
|
+
tokenProgram,
|
|
2066
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2067
|
+
})
|
|
2029
2068
|
.instruction();
|
|
2030
2069
|
return ix;
|
|
2031
2070
|
}
|
|
@@ -2034,60 +2073,43 @@ class CompressedTokenProgram {
|
|
|
2034
2073
|
*/
|
|
2035
2074
|
static async mintTo(params) {
|
|
2036
2075
|
const systemKeys = defaultStaticAccountsStruct();
|
|
2037
|
-
const { mint, feePayer, authority, merkleTree, toPubkey, amount } =
|
|
2038
|
-
|
|
2076
|
+
const { mint, feePayer, authority, merkleTree, toPubkey, amount, tokenProgramId, } = params;
|
|
2077
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2039
2078
|
const tokenPoolPda = this.deriveTokenPoolPda(mint);
|
|
2040
2079
|
const amounts = toArray(amount).map(amount => bn(amount));
|
|
2041
2080
|
const toPubkeys = toArray(toPubkey);
|
|
2042
2081
|
if (amounts.length !== toPubkeys.length) {
|
|
2043
|
-
throw new Error(
|
|
2044
|
-
'Amount and toPubkey arrays must have the same length',
|
|
2045
|
-
);
|
|
2082
|
+
throw new Error('Amount and toPubkey arrays must have the same length');
|
|
2046
2083
|
}
|
|
2047
2084
|
const instruction = await this.program.methods
|
|
2048
2085
|
.mintTo(toPubkeys, amounts, null)
|
|
2049
2086
|
.accounts({
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
solPoolPda: null,
|
|
2066
|
-
})
|
|
2087
|
+
feePayer,
|
|
2088
|
+
authority,
|
|
2089
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2090
|
+
mint,
|
|
2091
|
+
tokenPoolPda,
|
|
2092
|
+
tokenProgram,
|
|
2093
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2094
|
+
registeredProgramPda: systemKeys.registeredProgramPda,
|
|
2095
|
+
noopProgram: systemKeys.noopProgram,
|
|
2096
|
+
accountCompressionAuthority: systemKeys.accountCompressionAuthority,
|
|
2097
|
+
accountCompressionProgram: systemKeys.accountCompressionProgram,
|
|
2098
|
+
merkleTree: merkleTree ?? defaultTestStateTreeAccounts().merkleTree,
|
|
2099
|
+
selfProgram: this.programId,
|
|
2100
|
+
solPoolPda: null,
|
|
2101
|
+
})
|
|
2067
2102
|
.instruction();
|
|
2068
2103
|
return instruction;
|
|
2069
2104
|
}
|
|
2070
|
-
/// TODO: add compressBatch functionality for batch minting
|
|
2071
2105
|
/**
|
|
2072
|
-
* Mint tokens from
|
|
2106
|
+
* Mint tokens from registered SPL mint account to a compressed account
|
|
2073
2107
|
*/
|
|
2074
2108
|
static async approveAndMintTo(params) {
|
|
2075
|
-
const {
|
|
2076
|
-
mint,
|
|
2077
|
-
feePayer,
|
|
2078
|
-
authorityTokenAccount,
|
|
2079
|
-
authority,
|
|
2080
|
-
merkleTree,
|
|
2081
|
-
toPubkey,
|
|
2082
|
-
} = params;
|
|
2109
|
+
const { mint, feePayer, authorityTokenAccount, authority, merkleTree, toPubkey, tokenProgramId, } = params;
|
|
2083
2110
|
const amount = BigInt(params.amount.toString());
|
|
2084
2111
|
/// 1. Mint to existing ATA of mintAuthority.
|
|
2085
|
-
const splMintToInstruction = createMintToInstruction(
|
|
2086
|
-
mint,
|
|
2087
|
-
authorityTokenAccount,
|
|
2088
|
-
authority,
|
|
2089
|
-
amount,
|
|
2090
|
-
);
|
|
2112
|
+
const splMintToInstruction = createMintToInstruction(mint, authorityTokenAccount, authority, amount, [], tokenProgramId);
|
|
2091
2113
|
/// 2. Compress from mint authority ATA to recipient compressed account
|
|
2092
2114
|
const compressInstruction = await this.compress({
|
|
2093
2115
|
payer: feePayer,
|
|
@@ -2097,6 +2119,7 @@ class CompressedTokenProgram {
|
|
|
2097
2119
|
mint,
|
|
2098
2120
|
amount: params.amount,
|
|
2099
2121
|
outputStateTree: merkleTree,
|
|
2122
|
+
tokenProgramId,
|
|
2100
2123
|
});
|
|
2101
2124
|
return [splMintToInstruction, compressInstruction];
|
|
2102
2125
|
}
|
|
@@ -2104,33 +2127,15 @@ class CompressedTokenProgram {
|
|
|
2104
2127
|
* Construct transfer instruction for compressed tokens
|
|
2105
2128
|
*/
|
|
2106
2129
|
static async transfer(params) {
|
|
2107
|
-
const {
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
recentInputStateRootIndices,
|
|
2111
|
-
recentValidityProof,
|
|
2112
|
-
amount,
|
|
2113
|
-
outputStateTrees,
|
|
2114
|
-
toAddress,
|
|
2115
|
-
} = params;
|
|
2116
|
-
const tokenTransferOutputs = createTransferOutputState(
|
|
2117
|
-
inputCompressedTokenAccounts,
|
|
2118
|
-
toAddress,
|
|
2119
|
-
amount,
|
|
2120
|
-
);
|
|
2121
|
-
const {
|
|
2122
|
-
inputTokenDataWithContext,
|
|
2123
|
-
packedOutputTokenData,
|
|
2124
|
-
remainingAccountMetas,
|
|
2125
|
-
} = packCompressedTokenAccounts({
|
|
2130
|
+
const { payer, inputCompressedTokenAccounts, recentInputStateRootIndices, recentValidityProof, amount, outputStateTrees, toAddress, } = params;
|
|
2131
|
+
const tokenTransferOutputs = createTransferOutputState(inputCompressedTokenAccounts, toAddress, amount);
|
|
2132
|
+
const { inputTokenDataWithContext, packedOutputTokenData, remainingAccountMetas, } = packCompressedTokenAccounts({
|
|
2126
2133
|
inputCompressedTokenAccounts,
|
|
2127
2134
|
outputStateTrees,
|
|
2128
2135
|
rootIndices: recentInputStateRootIndices,
|
|
2129
2136
|
tokenTransferOutputs,
|
|
2130
2137
|
});
|
|
2131
|
-
const { mint, currentOwner } = parseTokenData(
|
|
2132
|
-
inputCompressedTokenAccounts,
|
|
2133
|
-
);
|
|
2138
|
+
const { mint, currentOwner } = parseTokenData(inputCompressedTokenAccounts);
|
|
2134
2139
|
const data = {
|
|
2135
2140
|
proof: recentValidityProof,
|
|
2136
2141
|
mint,
|
|
@@ -2142,32 +2147,24 @@ class CompressedTokenProgram {
|
|
|
2142
2147
|
cpiContext: null,
|
|
2143
2148
|
lamportsChangeAccountMerkleTreeIndex: null,
|
|
2144
2149
|
};
|
|
2145
|
-
const encodedData = this.program.coder.types.encode(
|
|
2146
|
-
|
|
2147
|
-
data,
|
|
2148
|
-
);
|
|
2149
|
-
const {
|
|
2150
|
-
accountCompressionAuthority,
|
|
2151
|
-
noopProgram,
|
|
2152
|
-
registeredProgramPda,
|
|
2153
|
-
accountCompressionProgram,
|
|
2154
|
-
} = defaultStaticAccountsStruct();
|
|
2150
|
+
const encodedData = this.program.coder.types.encode('CompressedTokenInstructionDataTransfer', data);
|
|
2151
|
+
const { accountCompressionAuthority, noopProgram, registeredProgramPda, accountCompressionProgram, } = defaultStaticAccountsStruct();
|
|
2155
2152
|
const instruction = await this.program.methods
|
|
2156
2153
|
.transfer(encodedData)
|
|
2157
2154
|
.accounts({
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2155
|
+
feePayer: payer,
|
|
2156
|
+
authority: currentOwner,
|
|
2157
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2158
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2159
|
+
registeredProgramPda: registeredProgramPda,
|
|
2160
|
+
noopProgram: noopProgram,
|
|
2161
|
+
accountCompressionAuthority: accountCompressionAuthority,
|
|
2162
|
+
accountCompressionProgram: accountCompressionProgram,
|
|
2163
|
+
selfProgram: this.programId,
|
|
2164
|
+
tokenPoolPda: null,
|
|
2165
|
+
compressOrDecompressTokenAccount: null,
|
|
2166
|
+
tokenProgram: null,
|
|
2167
|
+
})
|
|
2171
2168
|
.remainingAccounts(remainingAccountMetas)
|
|
2172
2169
|
.instruction();
|
|
2173
2170
|
return instruction;
|
|
@@ -2176,14 +2173,12 @@ class CompressedTokenProgram {
|
|
|
2176
2173
|
* Create lookup table instructions for the token program's default accounts.
|
|
2177
2174
|
*/
|
|
2178
2175
|
static async createTokenProgramLookupTable(params) {
|
|
2179
|
-
const { authority, mints, recentSlot, payer, remainingAccounts } =
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
recentSlot,
|
|
2186
|
-
});
|
|
2176
|
+
const { authority, mints, recentSlot, payer, remainingAccounts } = params;
|
|
2177
|
+
const [createInstruction, lookupTableAddress] = AddressLookupTableProgram.createLookupTable({
|
|
2178
|
+
authority,
|
|
2179
|
+
payer: authority,
|
|
2180
|
+
recentSlot,
|
|
2181
|
+
});
|
|
2187
2182
|
let optionalMintKeys = [];
|
|
2188
2183
|
if (mints) {
|
|
2189
2184
|
optionalMintKeys = [
|
|
@@ -2208,6 +2203,7 @@ class CompressedTokenProgram {
|
|
|
2208
2203
|
defaultTestStateTreeAccounts().addressQueue,
|
|
2209
2204
|
this.programId,
|
|
2210
2205
|
TOKEN_PROGRAM_ID,
|
|
2206
|
+
TOKEN_2022_PROGRAM_ID,
|
|
2211
2207
|
authority,
|
|
2212
2208
|
...optionalMintKeys,
|
|
2213
2209
|
...(remainingAccounts ?? []),
|
|
@@ -2223,19 +2219,14 @@ class CompressedTokenProgram {
|
|
|
2223
2219
|
* @returns compressInstruction
|
|
2224
2220
|
*/
|
|
2225
2221
|
static async compress(params) {
|
|
2226
|
-
const { payer, owner, source, toAddress, mint, outputStateTree } =
|
|
2227
|
-
params;
|
|
2222
|
+
const { payer, owner, source, toAddress, mint, outputStateTree, tokenProgramId, } = params;
|
|
2228
2223
|
if (Array.isArray(params.amount) !== Array.isArray(params.toAddress)) {
|
|
2229
|
-
throw new Error(
|
|
2230
|
-
'Both amount and toAddress must be arrays or both must be single values',
|
|
2231
|
-
);
|
|
2224
|
+
throw new Error('Both amount and toAddress must be arrays or both must be single values');
|
|
2232
2225
|
}
|
|
2233
2226
|
let tokenTransferOutputs;
|
|
2234
2227
|
if (Array.isArray(params.amount) && Array.isArray(params.toAddress)) {
|
|
2235
2228
|
if (params.amount.length !== params.toAddress.length) {
|
|
2236
|
-
throw new Error(
|
|
2237
|
-
'Amount and toAddress arrays must have the same length',
|
|
2238
|
-
);
|
|
2229
|
+
throw new Error('Amount and toAddress arrays must have the same length');
|
|
2239
2230
|
}
|
|
2240
2231
|
tokenTransferOutputs = params.amount.map((amt, index) => {
|
|
2241
2232
|
const amount = bn(amt);
|
|
@@ -2246,7 +2237,8 @@ class CompressedTokenProgram {
|
|
|
2246
2237
|
tlv: null,
|
|
2247
2238
|
};
|
|
2248
2239
|
});
|
|
2249
|
-
}
|
|
2240
|
+
}
|
|
2241
|
+
else {
|
|
2250
2242
|
tokenTransferOutputs = [
|
|
2251
2243
|
{
|
|
2252
2244
|
owner: toAddress,
|
|
@@ -2256,11 +2248,7 @@ class CompressedTokenProgram {
|
|
|
2256
2248
|
},
|
|
2257
2249
|
];
|
|
2258
2250
|
}
|
|
2259
|
-
const {
|
|
2260
|
-
inputTokenDataWithContext,
|
|
2261
|
-
packedOutputTokenData,
|
|
2262
|
-
remainingAccountMetas,
|
|
2263
|
-
} = packCompressedTokenAccounts({
|
|
2251
|
+
const { inputTokenDataWithContext, packedOutputTokenData, remainingAccountMetas, } = packCompressedTokenAccounts({
|
|
2264
2252
|
inputCompressedTokenAccounts: [],
|
|
2265
2253
|
outputStateTrees: outputStateTree,
|
|
2266
2254
|
rootIndices: [],
|
|
@@ -2274,36 +2262,31 @@ class CompressedTokenProgram {
|
|
|
2274
2262
|
outputCompressedAccounts: packedOutputTokenData,
|
|
2275
2263
|
compressOrDecompressAmount: Array.isArray(params.amount)
|
|
2276
2264
|
? params.amount
|
|
2277
|
-
|
|
2278
|
-
|
|
2265
|
+
.map(amt => new BN(amt))
|
|
2266
|
+
.reduce((sum, amt) => sum.add(amt), new BN(0))
|
|
2279
2267
|
: new BN(params.amount),
|
|
2280
2268
|
isCompress: true,
|
|
2281
2269
|
cpiContext: null,
|
|
2282
2270
|
lamportsChangeAccountMerkleTreeIndex: null,
|
|
2283
2271
|
};
|
|
2284
|
-
const encodedData = this.program.coder.types.encode(
|
|
2285
|
-
|
|
2286
|
-
data,
|
|
2287
|
-
);
|
|
2272
|
+
const encodedData = this.program.coder.types.encode('CompressedTokenInstructionDataTransfer', data);
|
|
2273
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2288
2274
|
const instruction = await this.program.methods
|
|
2289
2275
|
.transfer(encodedData)
|
|
2290
2276
|
.accounts({
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
compressOrDecompressTokenAccount: source, // token
|
|
2305
|
-
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2306
|
-
})
|
|
2277
|
+
feePayer: payer,
|
|
2278
|
+
authority: owner,
|
|
2279
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2280
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2281
|
+
registeredProgramPda: defaultStaticAccountsStruct().registeredProgramPda,
|
|
2282
|
+
noopProgram: defaultStaticAccountsStruct().noopProgram,
|
|
2283
|
+
accountCompressionAuthority: defaultStaticAccountsStruct().accountCompressionAuthority,
|
|
2284
|
+
accountCompressionProgram: defaultStaticAccountsStruct().accountCompressionProgram,
|
|
2285
|
+
selfProgram: this.programId,
|
|
2286
|
+
tokenPoolPda: this.deriveTokenPoolPda(mint),
|
|
2287
|
+
compressOrDecompressTokenAccount: source, // token
|
|
2288
|
+
tokenProgram,
|
|
2289
|
+
})
|
|
2307
2290
|
.remainingAccounts(remainingAccountMetas)
|
|
2308
2291
|
.instruction();
|
|
2309
2292
|
return instruction;
|
|
@@ -2312,33 +2295,17 @@ class CompressedTokenProgram {
|
|
|
2312
2295
|
* Construct decompress instruction
|
|
2313
2296
|
*/
|
|
2314
2297
|
static async decompress(params) {
|
|
2315
|
-
const {
|
|
2316
|
-
payer,
|
|
2317
|
-
inputCompressedTokenAccounts,
|
|
2318
|
-
toAddress,
|
|
2319
|
-
outputStateTree,
|
|
2320
|
-
recentValidityProof,
|
|
2321
|
-
recentInputStateRootIndices,
|
|
2322
|
-
} = params;
|
|
2298
|
+
const { payer, inputCompressedTokenAccounts, toAddress, outputStateTree, recentValidityProof, recentInputStateRootIndices, tokenProgramId, } = params;
|
|
2323
2299
|
const amount = bn(params.amount);
|
|
2324
|
-
const tokenTransferOutputs = createDecompressOutputState(
|
|
2325
|
-
inputCompressedTokenAccounts,
|
|
2326
|
-
amount,
|
|
2327
|
-
);
|
|
2300
|
+
const tokenTransferOutputs = createDecompressOutputState(inputCompressedTokenAccounts, amount);
|
|
2328
2301
|
/// Pack
|
|
2329
|
-
const {
|
|
2330
|
-
inputTokenDataWithContext,
|
|
2331
|
-
packedOutputTokenData,
|
|
2332
|
-
remainingAccountMetas,
|
|
2333
|
-
} = packCompressedTokenAccounts({
|
|
2302
|
+
const { inputTokenDataWithContext, packedOutputTokenData, remainingAccountMetas, } = packCompressedTokenAccounts({
|
|
2334
2303
|
inputCompressedTokenAccounts,
|
|
2335
2304
|
outputStateTrees: outputStateTree,
|
|
2336
2305
|
rootIndices: recentInputStateRootIndices,
|
|
2337
2306
|
tokenTransferOutputs: tokenTransferOutputs,
|
|
2338
2307
|
});
|
|
2339
|
-
const { mint, currentOwner } = parseTokenData(
|
|
2340
|
-
inputCompressedTokenAccounts,
|
|
2341
|
-
);
|
|
2308
|
+
const { mint, currentOwner } = parseTokenData(inputCompressedTokenAccounts);
|
|
2342
2309
|
const data = {
|
|
2343
2310
|
proof: recentValidityProof,
|
|
2344
2311
|
mint,
|
|
@@ -2350,45 +2317,31 @@ class CompressedTokenProgram {
|
|
|
2350
2317
|
cpiContext: null,
|
|
2351
2318
|
lamportsChangeAccountMerkleTreeIndex: null,
|
|
2352
2319
|
};
|
|
2353
|
-
const encodedData = this.program.coder.types.encode(
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
);
|
|
2357
|
-
const {
|
|
2358
|
-
accountCompressionAuthority,
|
|
2359
|
-
noopProgram,
|
|
2360
|
-
registeredProgramPda,
|
|
2361
|
-
accountCompressionProgram,
|
|
2362
|
-
} = defaultStaticAccountsStruct();
|
|
2320
|
+
const encodedData = this.program.coder.types.encode('CompressedTokenInstructionDataTransfer', data);
|
|
2321
|
+
const { accountCompressionAuthority, noopProgram, registeredProgramPda, accountCompressionProgram, } = defaultStaticAccountsStruct();
|
|
2322
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2363
2323
|
const instruction = await this.program.methods
|
|
2364
2324
|
.transfer(encodedData)
|
|
2365
2325
|
.accounts({
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2326
|
+
feePayer: payer,
|
|
2327
|
+
authority: currentOwner,
|
|
2328
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2329
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2330
|
+
registeredProgramPda: registeredProgramPda,
|
|
2331
|
+
noopProgram: noopProgram,
|
|
2332
|
+
accountCompressionAuthority: accountCompressionAuthority,
|
|
2333
|
+
accountCompressionProgram: accountCompressionProgram,
|
|
2334
|
+
selfProgram: this.programId,
|
|
2335
|
+
tokenPoolPda: this.deriveTokenPoolPda(mint),
|
|
2336
|
+
compressOrDecompressTokenAccount: toAddress,
|
|
2337
|
+
tokenProgram,
|
|
2338
|
+
})
|
|
2379
2339
|
.remainingAccounts(remainingAccountMetas)
|
|
2380
2340
|
.instruction();
|
|
2381
2341
|
return instruction;
|
|
2382
2342
|
}
|
|
2383
2343
|
static async mergeTokenAccounts(params) {
|
|
2384
|
-
const {
|
|
2385
|
-
payer,
|
|
2386
|
-
owner,
|
|
2387
|
-
inputCompressedTokenAccounts,
|
|
2388
|
-
outputStateTree,
|
|
2389
|
-
recentValidityProof,
|
|
2390
|
-
recentInputStateRootIndices,
|
|
2391
|
-
} = params;
|
|
2344
|
+
const { payer, owner, inputCompressedTokenAccounts, outputStateTree, recentValidityProof, recentInputStateRootIndices, } = params;
|
|
2392
2345
|
if (inputCompressedTokenAccounts.length > 3) {
|
|
2393
2346
|
throw new Error('Cannot merge more than 3 token accounts at once');
|
|
2394
2347
|
}
|
|
@@ -2396,10 +2349,7 @@ class CompressedTokenProgram {
|
|
|
2396
2349
|
payer,
|
|
2397
2350
|
inputCompressedTokenAccounts,
|
|
2398
2351
|
toAddress: owner,
|
|
2399
|
-
amount: inputCompressedTokenAccounts.reduce(
|
|
2400
|
-
(sum, account) => sum.add(account.parsed.amount),
|
|
2401
|
-
new BN(0),
|
|
2402
|
-
),
|
|
2352
|
+
amount: inputCompressedTokenAccounts.reduce((sum, account) => sum.add(account.parsed.amount), new BN(0)),
|
|
2403
2353
|
outputStateTrees: outputStateTree,
|
|
2404
2354
|
recentInputStateRootIndices,
|
|
2405
2355
|
recentValidityProof,
|
|
@@ -2407,14 +2357,8 @@ class CompressedTokenProgram {
|
|
|
2407
2357
|
return [ix];
|
|
2408
2358
|
}
|
|
2409
2359
|
static async compressSplTokenAccount(params) {
|
|
2410
|
-
const {
|
|
2411
|
-
|
|
2412
|
-
authority,
|
|
2413
|
-
tokenAccount,
|
|
2414
|
-
mint,
|
|
2415
|
-
remainingAmount,
|
|
2416
|
-
outputStateTree,
|
|
2417
|
-
} = params;
|
|
2360
|
+
const { feePayer, authority, tokenAccount, mint, remainingAmount, outputStateTree, tokenProgramId, } = params;
|
|
2361
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2418
2362
|
const remainingAccountMetas = [
|
|
2419
2363
|
{
|
|
2420
2364
|
pubkey: outputStateTree,
|
|
@@ -2425,27 +2369,27 @@ class CompressedTokenProgram {
|
|
|
2425
2369
|
const instruction = await this.program.methods
|
|
2426
2370
|
.compressSplTokenAccount(authority, remainingAmount ?? null, null)
|
|
2427
2371
|
.accounts({
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2443
|
-
systemProgram: SystemProgram.programId,
|
|
2444
|
-
})
|
|
2372
|
+
feePayer,
|
|
2373
|
+
authority,
|
|
2374
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2375
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2376
|
+
registeredProgramPda: defaultStaticAccountsStruct().registeredProgramPda,
|
|
2377
|
+
noopProgram: defaultStaticAccountsStruct().noopProgram,
|
|
2378
|
+
accountCompressionAuthority: defaultStaticAccountsStruct().accountCompressionAuthority,
|
|
2379
|
+
accountCompressionProgram: defaultStaticAccountsStruct().accountCompressionProgram,
|
|
2380
|
+
selfProgram: this.programId,
|
|
2381
|
+
tokenPoolPda: this.deriveTokenPoolPda(mint),
|
|
2382
|
+
compressOrDecompressTokenAccount: tokenAccount,
|
|
2383
|
+
tokenProgram,
|
|
2384
|
+
systemProgram: SystemProgram.programId,
|
|
2385
|
+
})
|
|
2445
2386
|
.remainingAccounts(remainingAccountMetas)
|
|
2446
2387
|
.instruction();
|
|
2447
2388
|
return instruction;
|
|
2448
2389
|
}
|
|
2390
|
+
static async get_mint_program_id(mint, connection) {
|
|
2391
|
+
return (await connection.getAccountInfo(mint))?.owner;
|
|
2392
|
+
}
|
|
2449
2393
|
}
|
|
2450
2394
|
|
|
2451
2395
|
/**
|
|
@@ -2463,22 +2407,11 @@ class CompressedTokenProgram {
|
|
|
2463
2407
|
*
|
|
2464
2408
|
* @return Signature of the confirmed transaction
|
|
2465
2409
|
*/
|
|
2466
|
-
async function approveAndMintTo(
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
authority,
|
|
2472
|
-
amount,
|
|
2473
|
-
merkleTree,
|
|
2474
|
-
confirmOptions,
|
|
2475
|
-
) {
|
|
2476
|
-
const authorityTokenAccount = await getOrCreateAssociatedTokenAccount(
|
|
2477
|
-
rpc,
|
|
2478
|
-
payer,
|
|
2479
|
-
mint,
|
|
2480
|
-
authority.publicKey,
|
|
2481
|
-
);
|
|
2410
|
+
async function approveAndMintTo(rpc, payer, mint, destination, authority, amount, merkleTree, confirmOptions, tokenProgramId) {
|
|
2411
|
+
tokenProgramId = tokenProgramId
|
|
2412
|
+
? tokenProgramId
|
|
2413
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2414
|
+
const authorityTokenAccount = await getOrCreateAssociatedTokenAccount(rpc, payer, mint, authority.publicKey, undefined, undefined, confirmOptions, tokenProgramId);
|
|
2482
2415
|
const ixs = await CompressedTokenProgram.approveAndMintTo({
|
|
2483
2416
|
feePayer: payer.publicKey,
|
|
2484
2417
|
mint,
|
|
@@ -2487,18 +2420,14 @@ async function approveAndMintTo(
|
|
|
2487
2420
|
amount,
|
|
2488
2421
|
toPubkey: destination,
|
|
2489
2422
|
merkleTree,
|
|
2423
|
+
tokenProgramId,
|
|
2490
2424
|
});
|
|
2491
2425
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2492
2426
|
const additionalSigners = dedupeSigner(payer, [authority]);
|
|
2493
|
-
const tx = buildAndSignTx(
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
],
|
|
2498
|
-
payer,
|
|
2499
|
-
blockhash,
|
|
2500
|
-
additionalSigners,
|
|
2501
|
-
);
|
|
2427
|
+
const tx = buildAndSignTx([
|
|
2428
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }),
|
|
2429
|
+
...ixs,
|
|
2430
|
+
], payer, blockhash, additionalSigners);
|
|
2502
2431
|
const txId = await sendAndConfirmTx(rpc, tx, confirmOptions);
|
|
2503
2432
|
return txId;
|
|
2504
2433
|
}
|
|
@@ -2521,17 +2450,10 @@ async function approveAndMintTo(
|
|
|
2521
2450
|
*
|
|
2522
2451
|
* @return Signature of the confirmed transaction
|
|
2523
2452
|
*/
|
|
2524
|
-
async function compress(
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
amount,
|
|
2529
|
-
owner,
|
|
2530
|
-
sourceTokenAccount,
|
|
2531
|
-
toAddress,
|
|
2532
|
-
merkleTree,
|
|
2533
|
-
confirmOptions,
|
|
2534
|
-
) {
|
|
2453
|
+
async function compress(rpc, payer, mint, amount, owner, sourceTokenAccount, toAddress, merkleTree, confirmOptions, tokenProgramId) {
|
|
2454
|
+
tokenProgramId = tokenProgramId
|
|
2455
|
+
? tokenProgramId
|
|
2456
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2535
2457
|
const compressIx = await CompressedTokenProgram.compress({
|
|
2536
2458
|
payer: payer.publicKey,
|
|
2537
2459
|
owner: owner.publicKey,
|
|
@@ -2540,26 +2462,17 @@ async function compress(
|
|
|
2540
2462
|
amount,
|
|
2541
2463
|
mint,
|
|
2542
2464
|
outputStateTree: merkleTree,
|
|
2465
|
+
tokenProgramId,
|
|
2543
2466
|
});
|
|
2544
2467
|
const blockhashCtx = await rpc.getLatestBlockhash();
|
|
2545
2468
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2546
|
-
const signedTx = buildAndSignTx(
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
payer,
|
|
2554
|
-
blockhashCtx.blockhash,
|
|
2555
|
-
additionalSigners,
|
|
2556
|
-
);
|
|
2557
|
-
const txId = await sendAndConfirmTx(
|
|
2558
|
-
rpc,
|
|
2559
|
-
signedTx,
|
|
2560
|
-
confirmOptions,
|
|
2561
|
-
blockhashCtx,
|
|
2562
|
-
);
|
|
2469
|
+
const signedTx = buildAndSignTx([
|
|
2470
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
2471
|
+
units: 1_000_000,
|
|
2472
|
+
}),
|
|
2473
|
+
compressIx,
|
|
2474
|
+
], payer, blockhashCtx.blockhash, additionalSigners);
|
|
2475
|
+
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions, blockhashCtx);
|
|
2563
2476
|
return txId;
|
|
2564
2477
|
}
|
|
2565
2478
|
|
|
@@ -2580,31 +2493,15 @@ async function compress(
|
|
|
2580
2493
|
*
|
|
2581
2494
|
* @return Signature of the confirmed transaction
|
|
2582
2495
|
*/
|
|
2583
|
-
async function transfer(
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
mint,
|
|
2587
|
-
amount,
|
|
2588
|
-
owner,
|
|
2589
|
-
toAddress,
|
|
2590
|
-
/// TODO: allow multiple
|
|
2591
|
-
merkleTree,
|
|
2592
|
-
confirmOptions,
|
|
2593
|
-
) {
|
|
2496
|
+
async function transfer(rpc, payer, mint, amount, owner, toAddress,
|
|
2497
|
+
/// TODO: allow multiple
|
|
2498
|
+
merkleTree, confirmOptions) {
|
|
2594
2499
|
amount = bn(amount);
|
|
2595
|
-
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
);
|
|
2601
|
-
const [inputAccounts] = selectMinCompressedTokenAccountsForTransfer(
|
|
2602
|
-
compressedTokenAccounts.items,
|
|
2603
|
-
amount,
|
|
2604
|
-
);
|
|
2605
|
-
const proof = await rpc.getValidityProof(
|
|
2606
|
-
inputAccounts.map(account => bn(account.compressedAccount.hash)),
|
|
2607
|
-
);
|
|
2500
|
+
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(owner.publicKey, {
|
|
2501
|
+
mint,
|
|
2502
|
+
});
|
|
2503
|
+
const [inputAccounts] = selectMinCompressedTokenAccountsForTransfer(compressedTokenAccounts.items, amount);
|
|
2504
|
+
const proof = await rpc.getValidityProof(inputAccounts.map(account => bn(account.compressedAccount.hash)));
|
|
2608
2505
|
const ix = await CompressedTokenProgram.transfer({
|
|
2609
2506
|
payer: payer.publicKey,
|
|
2610
2507
|
inputCompressedTokenAccounts: inputAccounts,
|
|
@@ -2616,12 +2513,7 @@ async function transfer(
|
|
|
2616
2513
|
});
|
|
2617
2514
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2618
2515
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2619
|
-
const signedTx = buildAndSignTx(
|
|
2620
|
-
[ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix],
|
|
2621
|
-
payer,
|
|
2622
|
-
blockhash,
|
|
2623
|
-
additionalSigners,
|
|
2624
|
-
);
|
|
2516
|
+
const signedTx = buildAndSignTx([ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix], payer, blockhash, additionalSigners);
|
|
2625
2517
|
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions);
|
|
2626
2518
|
return txId;
|
|
2627
2519
|
}
|
|
@@ -2638,17 +2530,14 @@ function selectMinCompressedTokenAccountsForTransfer(accounts, transferAmount) {
|
|
|
2638
2530
|
const selectedAccounts = [];
|
|
2639
2531
|
accounts.sort((a, b) => b.parsed.amount.cmp(a.parsed.amount));
|
|
2640
2532
|
for (const account of accounts) {
|
|
2641
|
-
if (accumulatedAmount.gte(bn(transferAmount)))
|
|
2533
|
+
if (accumulatedAmount.gte(bn(transferAmount)))
|
|
2534
|
+
break;
|
|
2642
2535
|
accumulatedAmount = accumulatedAmount.add(account.parsed.amount);
|
|
2643
|
-
accumulatedLamports = accumulatedLamports.add(
|
|
2644
|
-
account.compressedAccount.lamports,
|
|
2645
|
-
);
|
|
2536
|
+
accumulatedLamports = accumulatedLamports.add(account.compressedAccount.lamports);
|
|
2646
2537
|
selectedAccounts.push(account);
|
|
2647
2538
|
}
|
|
2648
2539
|
if (accumulatedAmount.lt(bn(transferAmount))) {
|
|
2649
|
-
throw new Error(
|
|
2650
|
-
`Not enough balance for transfer. Required: ${transferAmount.toString()}, available: ${accumulatedAmount.toString()}`,
|
|
2651
|
-
);
|
|
2540
|
+
throw new Error(`Not enough balance for transfer. Required: ${transferAmount.toString()}, available: ${accumulatedAmount.toString()}`);
|
|
2652
2541
|
}
|
|
2653
2542
|
return [
|
|
2654
2543
|
selectedAccounts,
|
|
@@ -2675,32 +2564,19 @@ function selectMinCompressedTokenAccountsForTransfer(accounts, transferAmount) {
|
|
|
2675
2564
|
*
|
|
2676
2565
|
* @return Signature of the confirmed transaction
|
|
2677
2566
|
*/
|
|
2678
|
-
async function decompress(
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
toAddress,
|
|
2685
|
-
/// TODO: allow multiple
|
|
2686
|
-
merkleTree,
|
|
2687
|
-
confirmOptions,
|
|
2688
|
-
) {
|
|
2567
|
+
async function decompress(rpc, payer, mint, amount, owner, toAddress,
|
|
2568
|
+
/// TODO: allow multiple
|
|
2569
|
+
merkleTree, confirmOptions, tokenProgramId) {
|
|
2570
|
+
tokenProgramId = tokenProgramId
|
|
2571
|
+
? tokenProgramId
|
|
2572
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2689
2573
|
amount = bn(amount);
|
|
2690
|
-
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
mint,
|
|
2694
|
-
},
|
|
2695
|
-
);
|
|
2574
|
+
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(owner.publicKey, {
|
|
2575
|
+
mint,
|
|
2576
|
+
});
|
|
2696
2577
|
/// TODO: consider using a different selection algorithm
|
|
2697
|
-
const [inputAccounts] = selectMinCompressedTokenAccountsForTransfer(
|
|
2698
|
-
|
|
2699
|
-
amount,
|
|
2700
|
-
);
|
|
2701
|
-
const proof = await rpc.getValidityProof(
|
|
2702
|
-
inputAccounts.map(account => bn(account.compressedAccount.hash)),
|
|
2703
|
-
);
|
|
2578
|
+
const [inputAccounts] = selectMinCompressedTokenAccountsForTransfer(compressedTokenAccounts.items, amount);
|
|
2579
|
+
const proof = await rpc.getValidityProof(inputAccounts.map(account => bn(account.compressedAccount.hash)));
|
|
2704
2580
|
const ix = await CompressedTokenProgram.decompress({
|
|
2705
2581
|
payer: payer.publicKey,
|
|
2706
2582
|
inputCompressedTokenAccounts: inputAccounts,
|
|
@@ -2709,15 +2585,11 @@ async function decompress(
|
|
|
2709
2585
|
outputStateTree: merkleTree,
|
|
2710
2586
|
recentInputStateRootIndices: proof.rootIndices,
|
|
2711
2587
|
recentValidityProof: proof.compressedProof,
|
|
2588
|
+
tokenProgramId,
|
|
2712
2589
|
});
|
|
2713
2590
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2714
2591
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2715
|
-
const signedTx = buildAndSignTx(
|
|
2716
|
-
[ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix],
|
|
2717
|
-
payer,
|
|
2718
|
-
blockhash,
|
|
2719
|
-
additionalSigners,
|
|
2720
|
-
);
|
|
2592
|
+
const signedTx = buildAndSignTx([ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix], payer, blockhash, additionalSigners);
|
|
2721
2593
|
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions);
|
|
2722
2594
|
return txId;
|
|
2723
2595
|
}
|
|
@@ -2731,19 +2603,13 @@ async function decompress(
|
|
|
2731
2603
|
* @param decimals Location of the decimal place
|
|
2732
2604
|
* @param keypair Optional keypair, defaulting to a new random one
|
|
2733
2605
|
* @param confirmOptions Options for confirming the transaction
|
|
2606
|
+
* @param isToken22 Whether to create a Token 2022 mint. Defaults to false.
|
|
2734
2607
|
*
|
|
2735
2608
|
* @return Address of the new mint and the transaction signature
|
|
2736
2609
|
*/
|
|
2737
|
-
async function createMint(
|
|
2738
|
-
rpc
|
|
2739
|
-
|
|
2740
|
-
mintAuthority,
|
|
2741
|
-
decimals,
|
|
2742
|
-
keypair = Keypair.generate(),
|
|
2743
|
-
confirmOptions,
|
|
2744
|
-
) {
|
|
2745
|
-
const rentExemptBalance =
|
|
2746
|
-
await rpc.getMinimumBalanceForRentExemption(MINT_SIZE);
|
|
2610
|
+
async function createMint(rpc, payer, mintAuthority, decimals, keypair = Keypair.generate(), confirmOptions, isToken22 = false) {
|
|
2611
|
+
const rentExemptBalance = await rpc.getMinimumBalanceForRentExemption(MINT_SIZE);
|
|
2612
|
+
const tokenProgramId = isToken22 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID;
|
|
2747
2613
|
const ixs = await CompressedTokenProgram.createMint({
|
|
2748
2614
|
feePayer: payer.publicKey,
|
|
2749
2615
|
mint: keypair.publicKey,
|
|
@@ -2751,6 +2617,7 @@ async function createMint(
|
|
|
2751
2617
|
authority: mintAuthority,
|
|
2752
2618
|
freezeAuthority: null, // TODO: add feature
|
|
2753
2619
|
rentExemptBalance,
|
|
2620
|
+
tokenProgramId,
|
|
2754
2621
|
});
|
|
2755
2622
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2756
2623
|
const additionalSigners = dedupeSigner(payer, [keypair]);
|
|
@@ -2776,16 +2643,10 @@ async function createMint(
|
|
|
2776
2643
|
*
|
|
2777
2644
|
* @return Signature of the confirmed transaction
|
|
2778
2645
|
*/
|
|
2779
|
-
async function mintTo(
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
destination,
|
|
2784
|
-
authority,
|
|
2785
|
-
amount,
|
|
2786
|
-
merkleTree,
|
|
2787
|
-
confirmOptions,
|
|
2788
|
-
) {
|
|
2646
|
+
async function mintTo(rpc, payer, mint, destination, authority, amount, merkleTree, confirmOptions, tokenProgramId) {
|
|
2647
|
+
tokenProgramId = tokenProgramId
|
|
2648
|
+
? tokenProgramId
|
|
2649
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2789
2650
|
const additionalSigners = dedupeSigner(payer, [authority]);
|
|
2790
2651
|
const ix = await CompressedTokenProgram.mintTo({
|
|
2791
2652
|
feePayer: payer.publicKey,
|
|
@@ -2794,14 +2655,10 @@ async function mintTo(
|
|
|
2794
2655
|
amount: amount,
|
|
2795
2656
|
toPubkey: destination,
|
|
2796
2657
|
merkleTree,
|
|
2658
|
+
tokenProgramId,
|
|
2797
2659
|
});
|
|
2798
2660
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2799
|
-
const tx = buildAndSignTx(
|
|
2800
|
-
[ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix],
|
|
2801
|
-
payer,
|
|
2802
|
-
blockhash,
|
|
2803
|
-
additionalSigners,
|
|
2804
|
-
);
|
|
2661
|
+
const tx = buildAndSignTx([ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix], payer, blockhash, additionalSigners);
|
|
2805
2662
|
const txId = await sendAndConfirmTx(rpc, tx, confirmOptions);
|
|
2806
2663
|
return txId;
|
|
2807
2664
|
}
|
|
@@ -2819,60 +2676,34 @@ async function mintTo(
|
|
|
2819
2676
|
*
|
|
2820
2677
|
* @return Array of transaction signatures
|
|
2821
2678
|
*/
|
|
2822
|
-
async function mergeTokenAccounts(
|
|
2823
|
-
rpc,
|
|
2824
|
-
payer,
|
|
2825
|
-
mint,
|
|
2826
|
-
owner,
|
|
2827
|
-
merkleTree,
|
|
2828
|
-
confirmOptions,
|
|
2829
|
-
) {
|
|
2830
|
-
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(
|
|
2831
|
-
owner.publicKey,
|
|
2832
|
-
{ mint },
|
|
2833
|
-
);
|
|
2679
|
+
async function mergeTokenAccounts(rpc, payer, mint, owner, merkleTree, confirmOptions) {
|
|
2680
|
+
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(owner.publicKey, { mint });
|
|
2834
2681
|
if (compressedTokenAccounts.items.length === 0) {
|
|
2835
|
-
throw new Error(
|
|
2836
|
-
`No compressed token accounts found for mint ${mint.toBase58()}`,
|
|
2837
|
-
);
|
|
2682
|
+
throw new Error(`No compressed token accounts found for mint ${mint.toBase58()}`);
|
|
2838
2683
|
}
|
|
2839
2684
|
if (compressedTokenAccounts.items.length >= 6) {
|
|
2840
|
-
throw new Error(
|
|
2841
|
-
`Too many compressed token accounts used for mint ${mint.toBase58()}`,
|
|
2842
|
-
);
|
|
2685
|
+
throw new Error(`Too many compressed token accounts used for mint ${mint.toBase58()}`);
|
|
2843
2686
|
}
|
|
2844
2687
|
const instructions = [
|
|
2845
2688
|
ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }),
|
|
2846
2689
|
];
|
|
2847
|
-
for (
|
|
2848
|
-
let i = 0;
|
|
2849
|
-
i < compressedTokenAccounts.items.slice(0, 6).length;
|
|
2850
|
-
i += 3
|
|
2851
|
-
) {
|
|
2690
|
+
for (let i = 0; i < compressedTokenAccounts.items.slice(0, 6).length; i += 3) {
|
|
2852
2691
|
const batch = compressedTokenAccounts.items.slice(i, i + 3);
|
|
2853
|
-
const proof = await rpc.getValidityProof(
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
recentValidityProof: proof.compressedProof,
|
|
2864
|
-
recentInputStateRootIndices: proof.rootIndices,
|
|
2865
|
-
});
|
|
2692
|
+
const proof = await rpc.getValidityProof(batch.map(account => bn(account.compressedAccount.hash)));
|
|
2693
|
+
const batchInstructions = await CompressedTokenProgram.mergeTokenAccounts({
|
|
2694
|
+
payer: payer.publicKey,
|
|
2695
|
+
owner: owner.publicKey,
|
|
2696
|
+
mint,
|
|
2697
|
+
inputCompressedTokenAccounts: batch,
|
|
2698
|
+
outputStateTree: merkleTree,
|
|
2699
|
+
recentValidityProof: proof.compressedProof,
|
|
2700
|
+
recentInputStateRootIndices: proof.rootIndices,
|
|
2701
|
+
});
|
|
2866
2702
|
instructions.push(...batchInstructions);
|
|
2867
2703
|
}
|
|
2868
2704
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2869
2705
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2870
|
-
const signedTx = buildAndSignTx(
|
|
2871
|
-
instructions,
|
|
2872
|
-
payer,
|
|
2873
|
-
blockhash,
|
|
2874
|
-
additionalSigners,
|
|
2875
|
-
);
|
|
2706
|
+
const signedTx = buildAndSignTx(instructions, payer, blockhash, additionalSigners);
|
|
2876
2707
|
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions);
|
|
2877
2708
|
return txId;
|
|
2878
2709
|
}
|
|
@@ -2888,10 +2719,14 @@ async function mergeTokenAccounts(
|
|
|
2888
2719
|
*
|
|
2889
2720
|
* @return transaction signature
|
|
2890
2721
|
*/
|
|
2891
|
-
async function createTokenPool(rpc, payer,
|
|
2722
|
+
async function createTokenPool(rpc, payer, mint, confirmOptions, tokenProgramId) {
|
|
2723
|
+
tokenProgramId = tokenProgramId
|
|
2724
|
+
? tokenProgramId
|
|
2725
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2892
2726
|
const ix = await CompressedTokenProgram.createTokenPool({
|
|
2893
2727
|
feePayer: payer.publicKey,
|
|
2894
|
-
mint
|
|
2728
|
+
mint,
|
|
2729
|
+
tokenProgramId,
|
|
2895
2730
|
});
|
|
2896
2731
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2897
2732
|
const tx = buildAndSignTx([ix], payer, blockhash);
|
|
@@ -2912,50 +2747,23 @@ async function createTokenPool(rpc, payer, mintAddress, confirmOptions) {
|
|
|
2912
2747
|
*
|
|
2913
2748
|
* @return Transaction signatures and the address of the created lookup table
|
|
2914
2749
|
*/
|
|
2915
|
-
async function createTokenProgramLookupTable(
|
|
2916
|
-
rpc,
|
|
2917
|
-
payer,
|
|
2918
|
-
authority,
|
|
2919
|
-
mints,
|
|
2920
|
-
additionalAccounts,
|
|
2921
|
-
) {
|
|
2750
|
+
async function createTokenProgramLookupTable(rpc, payer, authority, mints, additionalAccounts) {
|
|
2922
2751
|
const recentSlot = await rpc.getSlot('finalized');
|
|
2923
|
-
const { instructions, address } =
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
});
|
|
2752
|
+
const { instructions, address } = await CompressedTokenProgram.createTokenProgramLookupTable({
|
|
2753
|
+
payer: payer.publicKey,
|
|
2754
|
+
authority: authority.publicKey,
|
|
2755
|
+
mints,
|
|
2756
|
+
remainingAccounts: additionalAccounts,
|
|
2757
|
+
recentSlot,
|
|
2758
|
+
});
|
|
2931
2759
|
const additionalSigners = dedupeSigner(payer, [authority]);
|
|
2932
2760
|
const blockhashCtx = await rpc.getLatestBlockhash();
|
|
2933
|
-
const signedTx = buildAndSignTx(
|
|
2934
|
-
[instructions[0]],
|
|
2935
|
-
payer,
|
|
2936
|
-
blockhashCtx.blockhash,
|
|
2937
|
-
additionalSigners,
|
|
2938
|
-
);
|
|
2761
|
+
const signedTx = buildAndSignTx([instructions[0]], payer, blockhashCtx.blockhash, additionalSigners);
|
|
2939
2762
|
/// Must wait for the first instruction to be finalized.
|
|
2940
|
-
const txId = await sendAndConfirmTx(
|
|
2941
|
-
rpc,
|
|
2942
|
-
signedTx,
|
|
2943
|
-
{ commitment: 'finalized' },
|
|
2944
|
-
blockhashCtx,
|
|
2945
|
-
);
|
|
2763
|
+
const txId = await sendAndConfirmTx(rpc, signedTx, { commitment: 'finalized' }, blockhashCtx);
|
|
2946
2764
|
const blockhashCtx2 = await rpc.getLatestBlockhash();
|
|
2947
|
-
const signedTx2 = buildAndSignTx(
|
|
2948
|
-
|
|
2949
|
-
payer,
|
|
2950
|
-
blockhashCtx2.blockhash,
|
|
2951
|
-
additionalSigners,
|
|
2952
|
-
);
|
|
2953
|
-
const txId2 = await sendAndConfirmTx(
|
|
2954
|
-
rpc,
|
|
2955
|
-
signedTx2,
|
|
2956
|
-
{ commitment: 'finalized' },
|
|
2957
|
-
blockhashCtx2,
|
|
2958
|
-
);
|
|
2765
|
+
const signedTx2 = buildAndSignTx([instructions[1]], payer, blockhashCtx2.blockhash, additionalSigners);
|
|
2766
|
+
const txId2 = await sendAndConfirmTx(rpc, signedTx2, { commitment: 'finalized' }, blockhashCtx2);
|
|
2959
2767
|
return { txIds: [txId, txId2], address };
|
|
2960
2768
|
}
|
|
2961
2769
|
|
|
@@ -2973,16 +2781,10 @@ async function createTokenProgramLookupTable(
|
|
|
2973
2781
|
*
|
|
2974
2782
|
* @return Signature of the confirmed transaction
|
|
2975
2783
|
*/
|
|
2976
|
-
async function compressSplTokenAccount(
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
owner,
|
|
2981
|
-
tokenAccount,
|
|
2982
|
-
outputStateTree,
|
|
2983
|
-
remainingAmount,
|
|
2984
|
-
confirmOptions,
|
|
2985
|
-
) {
|
|
2784
|
+
async function compressSplTokenAccount(rpc, payer, mint, owner, tokenAccount, outputStateTree, remainingAmount, confirmOptions, tokenProgramId) {
|
|
2785
|
+
tokenProgramId = tokenProgramId
|
|
2786
|
+
? tokenProgramId
|
|
2787
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2986
2788
|
const compressIx = await CompressedTokenProgram.compressSplTokenAccount({
|
|
2987
2789
|
feePayer: payer.publicKey,
|
|
2988
2790
|
authority: owner.publicKey,
|
|
@@ -2990,51 +2792,19 @@ async function compressSplTokenAccount(
|
|
|
2990
2792
|
mint,
|
|
2991
2793
|
remainingAmount,
|
|
2992
2794
|
outputStateTree,
|
|
2795
|
+
tokenProgramId,
|
|
2993
2796
|
});
|
|
2994
2797
|
const blockhashCtx = await rpc.getLatestBlockhash();
|
|
2995
2798
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2996
|
-
const signedTx = buildAndSignTx(
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
payer,
|
|
3004
|
-
blockhashCtx.blockhash,
|
|
3005
|
-
additionalSigners,
|
|
3006
|
-
);
|
|
3007
|
-
const txId = await sendAndConfirmTx(
|
|
3008
|
-
rpc,
|
|
3009
|
-
signedTx,
|
|
3010
|
-
confirmOptions,
|
|
3011
|
-
blockhashCtx,
|
|
3012
|
-
);
|
|
2799
|
+
const signedTx = buildAndSignTx([
|
|
2800
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
2801
|
+
units: 1_000_000,
|
|
2802
|
+
}),
|
|
2803
|
+
compressIx,
|
|
2804
|
+
], payer, blockhashCtx.blockhash, additionalSigners);
|
|
2805
|
+
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions, blockhashCtx);
|
|
3013
2806
|
return txId;
|
|
3014
2807
|
}
|
|
3015
2808
|
|
|
3016
|
-
export {
|
|
3017
|
-
CPI_AUTHORITY_SEED,
|
|
3018
|
-
CompressedTokenProgram,
|
|
3019
|
-
IDL,
|
|
3020
|
-
POOL_SEED,
|
|
3021
|
-
SPL_TOKEN_MINT_RENT_EXEMPT_BALANCE,
|
|
3022
|
-
approveAndMintTo,
|
|
3023
|
-
compress,
|
|
3024
|
-
compressSplTokenAccount,
|
|
3025
|
-
createDecompressOutputState,
|
|
3026
|
-
createMint,
|
|
3027
|
-
createTokenPool,
|
|
3028
|
-
createTokenProgramLookupTable,
|
|
3029
|
-
createTransferOutputState,
|
|
3030
|
-
decompress,
|
|
3031
|
-
mergeTokenAccounts,
|
|
3032
|
-
mintTo,
|
|
3033
|
-
packCompressedTokenAccounts,
|
|
3034
|
-
parseTokenData,
|
|
3035
|
-
selectMinCompressedTokenAccountsForTransfer,
|
|
3036
|
-
sumUpTokenAmount,
|
|
3037
|
-
transfer,
|
|
3038
|
-
validateSameTokenOwner,
|
|
3039
|
-
};
|
|
2809
|
+
export { CPI_AUTHORITY_SEED, CompressedTokenProgram, IDL, POOL_SEED, SPL_TOKEN_MINT_RENT_EXEMPT_BALANCE, approveAndMintTo, compress, compressSplTokenAccount, createDecompressOutputState, createMint, createTokenPool, createTokenProgramLookupTable, createTransferOutputState, decompress, mergeTokenAccounts, mintTo, packCompressedTokenAccounts, parseTokenData, selectMinCompressedTokenAccountsForTransfer, sumUpTokenAmount, transfer, validateSameTokenOwner };
|
|
3040
2810
|
//# sourceMappingURL=index.js.map
|