@lightprotocol/compressed-token 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/browser/index.cjs +430 -703
- package/dist/cjs/browser/index.cjs.map +1 -1
- package/dist/cjs/node/index.cjs +430 -703
- package/dist/cjs/node/index.cjs.map +1 -1
- package/dist/es/browser/index.js +395 -632
- package/dist/es/browser/index.js.map +1 -1
- package/dist/types/index.d.ts +270 -278
- 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,43 +2010,33 @@ 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
2022
|
* Construct createMint instruction for compressed tokens
|
|
1988
2023
|
*/
|
|
1989
2024
|
static async createMint(params) {
|
|
1990
|
-
const { mint, authority, feePayer, rentExemptBalance } = params;
|
|
2025
|
+
const { mint, authority, feePayer, rentExemptBalance, tokenProgramId, freezeAuthority, mintSize, } = params;
|
|
2026
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
1991
2027
|
/// Create and initialize SPL Mint account
|
|
1992
2028
|
const createMintAccountInstruction = SystemProgram.createAccount({
|
|
1993
2029
|
fromPubkey: feePayer,
|
|
1994
2030
|
lamports: rentExemptBalance,
|
|
1995
2031
|
newAccountPubkey: mint,
|
|
1996
|
-
programId:
|
|
1997
|
-
space: MINT_SIZE,
|
|
2032
|
+
programId: tokenProgram,
|
|
2033
|
+
space: mintSize ?? MINT_SIZE,
|
|
1998
2034
|
});
|
|
1999
|
-
const initializeMintInstruction = createInitializeMint2Instruction(
|
|
2000
|
-
mint,
|
|
2001
|
-
params.decimals,
|
|
2002
|
-
authority,
|
|
2003
|
-
params.freezeAuthority,
|
|
2004
|
-
TOKEN_PROGRAM_ID,
|
|
2005
|
-
);
|
|
2035
|
+
const initializeMintInstruction = createInitializeMint2Instruction(mint, params.decimals, authority, freezeAuthority, tokenProgram);
|
|
2006
2036
|
const ix = await this.createTokenPool({
|
|
2007
2037
|
feePayer,
|
|
2008
2038
|
mint,
|
|
2039
|
+
tokenProgramId: tokenProgram,
|
|
2009
2040
|
});
|
|
2010
2041
|
return [createMintAccountInstruction, initializeMintInstruction, ix];
|
|
2011
2042
|
}
|
|
@@ -2014,18 +2045,19 @@ class CompressedTokenProgram {
|
|
|
2014
2045
|
* For new mints, use `CompressedTokenProgram.createMint`.
|
|
2015
2046
|
*/
|
|
2016
2047
|
static async createTokenPool(params) {
|
|
2017
|
-
const { mint, feePayer } = params;
|
|
2048
|
+
const { mint, feePayer, tokenProgramId } = params;
|
|
2049
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2018
2050
|
const tokenPoolPda = this.deriveTokenPoolPda(mint);
|
|
2019
2051
|
const ix = await this.program.methods
|
|
2020
2052
|
.createTokenPool()
|
|
2021
2053
|
.accounts({
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2054
|
+
mint,
|
|
2055
|
+
feePayer,
|
|
2056
|
+
tokenPoolPda,
|
|
2057
|
+
systemProgram: SystemProgram.programId,
|
|
2058
|
+
tokenProgram,
|
|
2059
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2060
|
+
})
|
|
2029
2061
|
.instruction();
|
|
2030
2062
|
return ix;
|
|
2031
2063
|
}
|
|
@@ -2034,60 +2066,43 @@ class CompressedTokenProgram {
|
|
|
2034
2066
|
*/
|
|
2035
2067
|
static async mintTo(params) {
|
|
2036
2068
|
const systemKeys = defaultStaticAccountsStruct();
|
|
2037
|
-
const { mint, feePayer, authority, merkleTree, toPubkey, amount } =
|
|
2038
|
-
|
|
2069
|
+
const { mint, feePayer, authority, merkleTree, toPubkey, amount, tokenProgramId, } = params;
|
|
2070
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2039
2071
|
const tokenPoolPda = this.deriveTokenPoolPda(mint);
|
|
2040
2072
|
const amounts = toArray(amount).map(amount => bn(amount));
|
|
2041
2073
|
const toPubkeys = toArray(toPubkey);
|
|
2042
2074
|
if (amounts.length !== toPubkeys.length) {
|
|
2043
|
-
throw new Error(
|
|
2044
|
-
'Amount and toPubkey arrays must have the same length',
|
|
2045
|
-
);
|
|
2075
|
+
throw new Error('Amount and toPubkey arrays must have the same length');
|
|
2046
2076
|
}
|
|
2047
2077
|
const instruction = await this.program.methods
|
|
2048
2078
|
.mintTo(toPubkeys, amounts, null)
|
|
2049
2079
|
.accounts({
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
solPoolPda: null,
|
|
2066
|
-
})
|
|
2080
|
+
feePayer,
|
|
2081
|
+
authority,
|
|
2082
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2083
|
+
mint,
|
|
2084
|
+
tokenPoolPda,
|
|
2085
|
+
tokenProgram,
|
|
2086
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2087
|
+
registeredProgramPda: systemKeys.registeredProgramPda,
|
|
2088
|
+
noopProgram: systemKeys.noopProgram,
|
|
2089
|
+
accountCompressionAuthority: systemKeys.accountCompressionAuthority,
|
|
2090
|
+
accountCompressionProgram: systemKeys.accountCompressionProgram,
|
|
2091
|
+
merkleTree: merkleTree ?? defaultTestStateTreeAccounts().merkleTree,
|
|
2092
|
+
selfProgram: this.programId,
|
|
2093
|
+
solPoolPda: null,
|
|
2094
|
+
})
|
|
2067
2095
|
.instruction();
|
|
2068
2096
|
return instruction;
|
|
2069
2097
|
}
|
|
2070
|
-
/// TODO: add compressBatch functionality for batch minting
|
|
2071
2098
|
/**
|
|
2072
|
-
* Mint tokens from
|
|
2099
|
+
* Mint tokens from registered SPL mint account to a compressed account
|
|
2073
2100
|
*/
|
|
2074
2101
|
static async approveAndMintTo(params) {
|
|
2075
|
-
const {
|
|
2076
|
-
mint,
|
|
2077
|
-
feePayer,
|
|
2078
|
-
authorityTokenAccount,
|
|
2079
|
-
authority,
|
|
2080
|
-
merkleTree,
|
|
2081
|
-
toPubkey,
|
|
2082
|
-
} = params;
|
|
2102
|
+
const { mint, feePayer, authorityTokenAccount, authority, merkleTree, toPubkey, tokenProgramId, } = params;
|
|
2083
2103
|
const amount = BigInt(params.amount.toString());
|
|
2084
2104
|
/// 1. Mint to existing ATA of mintAuthority.
|
|
2085
|
-
const splMintToInstruction = createMintToInstruction(
|
|
2086
|
-
mint,
|
|
2087
|
-
authorityTokenAccount,
|
|
2088
|
-
authority,
|
|
2089
|
-
amount,
|
|
2090
|
-
);
|
|
2105
|
+
const splMintToInstruction = createMintToInstruction(mint, authorityTokenAccount, authority, amount, [], tokenProgramId);
|
|
2091
2106
|
/// 2. Compress from mint authority ATA to recipient compressed account
|
|
2092
2107
|
const compressInstruction = await this.compress({
|
|
2093
2108
|
payer: feePayer,
|
|
@@ -2097,6 +2112,7 @@ class CompressedTokenProgram {
|
|
|
2097
2112
|
mint,
|
|
2098
2113
|
amount: params.amount,
|
|
2099
2114
|
outputStateTree: merkleTree,
|
|
2115
|
+
tokenProgramId,
|
|
2100
2116
|
});
|
|
2101
2117
|
return [splMintToInstruction, compressInstruction];
|
|
2102
2118
|
}
|
|
@@ -2104,33 +2120,15 @@ class CompressedTokenProgram {
|
|
|
2104
2120
|
* Construct transfer instruction for compressed tokens
|
|
2105
2121
|
*/
|
|
2106
2122
|
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({
|
|
2123
|
+
const { payer, inputCompressedTokenAccounts, recentInputStateRootIndices, recentValidityProof, amount, outputStateTrees, toAddress, } = params;
|
|
2124
|
+
const tokenTransferOutputs = createTransferOutputState(inputCompressedTokenAccounts, toAddress, amount);
|
|
2125
|
+
const { inputTokenDataWithContext, packedOutputTokenData, remainingAccountMetas, } = packCompressedTokenAccounts({
|
|
2126
2126
|
inputCompressedTokenAccounts,
|
|
2127
2127
|
outputStateTrees,
|
|
2128
2128
|
rootIndices: recentInputStateRootIndices,
|
|
2129
2129
|
tokenTransferOutputs,
|
|
2130
2130
|
});
|
|
2131
|
-
const { mint, currentOwner } = parseTokenData(
|
|
2132
|
-
inputCompressedTokenAccounts,
|
|
2133
|
-
);
|
|
2131
|
+
const { mint, currentOwner } = parseTokenData(inputCompressedTokenAccounts);
|
|
2134
2132
|
const data = {
|
|
2135
2133
|
proof: recentValidityProof,
|
|
2136
2134
|
mint,
|
|
@@ -2142,32 +2140,24 @@ class CompressedTokenProgram {
|
|
|
2142
2140
|
cpiContext: null,
|
|
2143
2141
|
lamportsChangeAccountMerkleTreeIndex: null,
|
|
2144
2142
|
};
|
|
2145
|
-
const encodedData = this.program.coder.types.encode(
|
|
2146
|
-
|
|
2147
|
-
data,
|
|
2148
|
-
);
|
|
2149
|
-
const {
|
|
2150
|
-
accountCompressionAuthority,
|
|
2151
|
-
noopProgram,
|
|
2152
|
-
registeredProgramPda,
|
|
2153
|
-
accountCompressionProgram,
|
|
2154
|
-
} = defaultStaticAccountsStruct();
|
|
2143
|
+
const encodedData = this.program.coder.types.encode('CompressedTokenInstructionDataTransfer', data);
|
|
2144
|
+
const { accountCompressionAuthority, noopProgram, registeredProgramPda, accountCompressionProgram, } = defaultStaticAccountsStruct();
|
|
2155
2145
|
const instruction = await this.program.methods
|
|
2156
2146
|
.transfer(encodedData)
|
|
2157
2147
|
.accounts({
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2148
|
+
feePayer: payer,
|
|
2149
|
+
authority: currentOwner,
|
|
2150
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2151
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2152
|
+
registeredProgramPda: registeredProgramPda,
|
|
2153
|
+
noopProgram: noopProgram,
|
|
2154
|
+
accountCompressionAuthority: accountCompressionAuthority,
|
|
2155
|
+
accountCompressionProgram: accountCompressionProgram,
|
|
2156
|
+
selfProgram: this.programId,
|
|
2157
|
+
tokenPoolPda: null,
|
|
2158
|
+
compressOrDecompressTokenAccount: null,
|
|
2159
|
+
tokenProgram: null,
|
|
2160
|
+
})
|
|
2171
2161
|
.remainingAccounts(remainingAccountMetas)
|
|
2172
2162
|
.instruction();
|
|
2173
2163
|
return instruction;
|
|
@@ -2176,14 +2166,12 @@ class CompressedTokenProgram {
|
|
|
2176
2166
|
* Create lookup table instructions for the token program's default accounts.
|
|
2177
2167
|
*/
|
|
2178
2168
|
static async createTokenProgramLookupTable(params) {
|
|
2179
|
-
const { authority, mints, recentSlot, payer, remainingAccounts } =
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
recentSlot,
|
|
2186
|
-
});
|
|
2169
|
+
const { authority, mints, recentSlot, payer, remainingAccounts } = params;
|
|
2170
|
+
const [createInstruction, lookupTableAddress] = AddressLookupTableProgram.createLookupTable({
|
|
2171
|
+
authority,
|
|
2172
|
+
payer: authority,
|
|
2173
|
+
recentSlot,
|
|
2174
|
+
});
|
|
2187
2175
|
let optionalMintKeys = [];
|
|
2188
2176
|
if (mints) {
|
|
2189
2177
|
optionalMintKeys = [
|
|
@@ -2208,6 +2196,7 @@ class CompressedTokenProgram {
|
|
|
2208
2196
|
defaultTestStateTreeAccounts().addressQueue,
|
|
2209
2197
|
this.programId,
|
|
2210
2198
|
TOKEN_PROGRAM_ID,
|
|
2199
|
+
TOKEN_2022_PROGRAM_ID,
|
|
2211
2200
|
authority,
|
|
2212
2201
|
...optionalMintKeys,
|
|
2213
2202
|
...(remainingAccounts ?? []),
|
|
@@ -2223,19 +2212,14 @@ class CompressedTokenProgram {
|
|
|
2223
2212
|
* @returns compressInstruction
|
|
2224
2213
|
*/
|
|
2225
2214
|
static async compress(params) {
|
|
2226
|
-
const { payer, owner, source, toAddress, mint, outputStateTree } =
|
|
2227
|
-
params;
|
|
2215
|
+
const { payer, owner, source, toAddress, mint, outputStateTree, tokenProgramId, } = params;
|
|
2228
2216
|
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
|
-
);
|
|
2217
|
+
throw new Error('Both amount and toAddress must be arrays or both must be single values');
|
|
2232
2218
|
}
|
|
2233
2219
|
let tokenTransferOutputs;
|
|
2234
2220
|
if (Array.isArray(params.amount) && Array.isArray(params.toAddress)) {
|
|
2235
2221
|
if (params.amount.length !== params.toAddress.length) {
|
|
2236
|
-
throw new Error(
|
|
2237
|
-
'Amount and toAddress arrays must have the same length',
|
|
2238
|
-
);
|
|
2222
|
+
throw new Error('Amount and toAddress arrays must have the same length');
|
|
2239
2223
|
}
|
|
2240
2224
|
tokenTransferOutputs = params.amount.map((amt, index) => {
|
|
2241
2225
|
const amount = bn(amt);
|
|
@@ -2246,7 +2230,8 @@ class CompressedTokenProgram {
|
|
|
2246
2230
|
tlv: null,
|
|
2247
2231
|
};
|
|
2248
2232
|
});
|
|
2249
|
-
}
|
|
2233
|
+
}
|
|
2234
|
+
else {
|
|
2250
2235
|
tokenTransferOutputs = [
|
|
2251
2236
|
{
|
|
2252
2237
|
owner: toAddress,
|
|
@@ -2256,11 +2241,7 @@ class CompressedTokenProgram {
|
|
|
2256
2241
|
},
|
|
2257
2242
|
];
|
|
2258
2243
|
}
|
|
2259
|
-
const {
|
|
2260
|
-
inputTokenDataWithContext,
|
|
2261
|
-
packedOutputTokenData,
|
|
2262
|
-
remainingAccountMetas,
|
|
2263
|
-
} = packCompressedTokenAccounts({
|
|
2244
|
+
const { inputTokenDataWithContext, packedOutputTokenData, remainingAccountMetas, } = packCompressedTokenAccounts({
|
|
2264
2245
|
inputCompressedTokenAccounts: [],
|
|
2265
2246
|
outputStateTrees: outputStateTree,
|
|
2266
2247
|
rootIndices: [],
|
|
@@ -2274,36 +2255,31 @@ class CompressedTokenProgram {
|
|
|
2274
2255
|
outputCompressedAccounts: packedOutputTokenData,
|
|
2275
2256
|
compressOrDecompressAmount: Array.isArray(params.amount)
|
|
2276
2257
|
? params.amount
|
|
2277
|
-
|
|
2278
|
-
|
|
2258
|
+
.map(amt => new BN(amt))
|
|
2259
|
+
.reduce((sum, amt) => sum.add(amt), new BN(0))
|
|
2279
2260
|
: new BN(params.amount),
|
|
2280
2261
|
isCompress: true,
|
|
2281
2262
|
cpiContext: null,
|
|
2282
2263
|
lamportsChangeAccountMerkleTreeIndex: null,
|
|
2283
2264
|
};
|
|
2284
|
-
const encodedData = this.program.coder.types.encode(
|
|
2285
|
-
|
|
2286
|
-
data,
|
|
2287
|
-
);
|
|
2265
|
+
const encodedData = this.program.coder.types.encode('CompressedTokenInstructionDataTransfer', data);
|
|
2266
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2288
2267
|
const instruction = await this.program.methods
|
|
2289
2268
|
.transfer(encodedData)
|
|
2290
2269
|
.accounts({
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
compressOrDecompressTokenAccount: source, // token
|
|
2305
|
-
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2306
|
-
})
|
|
2270
|
+
feePayer: payer,
|
|
2271
|
+
authority: owner,
|
|
2272
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2273
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2274
|
+
registeredProgramPda: defaultStaticAccountsStruct().registeredProgramPda,
|
|
2275
|
+
noopProgram: defaultStaticAccountsStruct().noopProgram,
|
|
2276
|
+
accountCompressionAuthority: defaultStaticAccountsStruct().accountCompressionAuthority,
|
|
2277
|
+
accountCompressionProgram: defaultStaticAccountsStruct().accountCompressionProgram,
|
|
2278
|
+
selfProgram: this.programId,
|
|
2279
|
+
tokenPoolPda: this.deriveTokenPoolPda(mint),
|
|
2280
|
+
compressOrDecompressTokenAccount: source, // token
|
|
2281
|
+
tokenProgram,
|
|
2282
|
+
})
|
|
2307
2283
|
.remainingAccounts(remainingAccountMetas)
|
|
2308
2284
|
.instruction();
|
|
2309
2285
|
return instruction;
|
|
@@ -2312,33 +2288,17 @@ class CompressedTokenProgram {
|
|
|
2312
2288
|
* Construct decompress instruction
|
|
2313
2289
|
*/
|
|
2314
2290
|
static async decompress(params) {
|
|
2315
|
-
const {
|
|
2316
|
-
payer,
|
|
2317
|
-
inputCompressedTokenAccounts,
|
|
2318
|
-
toAddress,
|
|
2319
|
-
outputStateTree,
|
|
2320
|
-
recentValidityProof,
|
|
2321
|
-
recentInputStateRootIndices,
|
|
2322
|
-
} = params;
|
|
2291
|
+
const { payer, inputCompressedTokenAccounts, toAddress, outputStateTree, recentValidityProof, recentInputStateRootIndices, tokenProgramId, } = params;
|
|
2323
2292
|
const amount = bn(params.amount);
|
|
2324
|
-
const tokenTransferOutputs = createDecompressOutputState(
|
|
2325
|
-
inputCompressedTokenAccounts,
|
|
2326
|
-
amount,
|
|
2327
|
-
);
|
|
2293
|
+
const tokenTransferOutputs = createDecompressOutputState(inputCompressedTokenAccounts, amount);
|
|
2328
2294
|
/// Pack
|
|
2329
|
-
const {
|
|
2330
|
-
inputTokenDataWithContext,
|
|
2331
|
-
packedOutputTokenData,
|
|
2332
|
-
remainingAccountMetas,
|
|
2333
|
-
} = packCompressedTokenAccounts({
|
|
2295
|
+
const { inputTokenDataWithContext, packedOutputTokenData, remainingAccountMetas, } = packCompressedTokenAccounts({
|
|
2334
2296
|
inputCompressedTokenAccounts,
|
|
2335
2297
|
outputStateTrees: outputStateTree,
|
|
2336
2298
|
rootIndices: recentInputStateRootIndices,
|
|
2337
2299
|
tokenTransferOutputs: tokenTransferOutputs,
|
|
2338
2300
|
});
|
|
2339
|
-
const { mint, currentOwner } = parseTokenData(
|
|
2340
|
-
inputCompressedTokenAccounts,
|
|
2341
|
-
);
|
|
2301
|
+
const { mint, currentOwner } = parseTokenData(inputCompressedTokenAccounts);
|
|
2342
2302
|
const data = {
|
|
2343
2303
|
proof: recentValidityProof,
|
|
2344
2304
|
mint,
|
|
@@ -2350,45 +2310,31 @@ class CompressedTokenProgram {
|
|
|
2350
2310
|
cpiContext: null,
|
|
2351
2311
|
lamportsChangeAccountMerkleTreeIndex: null,
|
|
2352
2312
|
};
|
|
2353
|
-
const encodedData = this.program.coder.types.encode(
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
);
|
|
2357
|
-
const {
|
|
2358
|
-
accountCompressionAuthority,
|
|
2359
|
-
noopProgram,
|
|
2360
|
-
registeredProgramPda,
|
|
2361
|
-
accountCompressionProgram,
|
|
2362
|
-
} = defaultStaticAccountsStruct();
|
|
2313
|
+
const encodedData = this.program.coder.types.encode('CompressedTokenInstructionDataTransfer', data);
|
|
2314
|
+
const { accountCompressionAuthority, noopProgram, registeredProgramPda, accountCompressionProgram, } = defaultStaticAccountsStruct();
|
|
2315
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2363
2316
|
const instruction = await this.program.methods
|
|
2364
2317
|
.transfer(encodedData)
|
|
2365
2318
|
.accounts({
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2319
|
+
feePayer: payer,
|
|
2320
|
+
authority: currentOwner,
|
|
2321
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2322
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2323
|
+
registeredProgramPda: registeredProgramPda,
|
|
2324
|
+
noopProgram: noopProgram,
|
|
2325
|
+
accountCompressionAuthority: accountCompressionAuthority,
|
|
2326
|
+
accountCompressionProgram: accountCompressionProgram,
|
|
2327
|
+
selfProgram: this.programId,
|
|
2328
|
+
tokenPoolPda: this.deriveTokenPoolPda(mint),
|
|
2329
|
+
compressOrDecompressTokenAccount: toAddress,
|
|
2330
|
+
tokenProgram,
|
|
2331
|
+
})
|
|
2379
2332
|
.remainingAccounts(remainingAccountMetas)
|
|
2380
2333
|
.instruction();
|
|
2381
2334
|
return instruction;
|
|
2382
2335
|
}
|
|
2383
2336
|
static async mergeTokenAccounts(params) {
|
|
2384
|
-
const {
|
|
2385
|
-
payer,
|
|
2386
|
-
owner,
|
|
2387
|
-
inputCompressedTokenAccounts,
|
|
2388
|
-
outputStateTree,
|
|
2389
|
-
recentValidityProof,
|
|
2390
|
-
recentInputStateRootIndices,
|
|
2391
|
-
} = params;
|
|
2337
|
+
const { payer, owner, inputCompressedTokenAccounts, outputStateTree, recentValidityProof, recentInputStateRootIndices, } = params;
|
|
2392
2338
|
if (inputCompressedTokenAccounts.length > 3) {
|
|
2393
2339
|
throw new Error('Cannot merge more than 3 token accounts at once');
|
|
2394
2340
|
}
|
|
@@ -2396,10 +2342,7 @@ class CompressedTokenProgram {
|
|
|
2396
2342
|
payer,
|
|
2397
2343
|
inputCompressedTokenAccounts,
|
|
2398
2344
|
toAddress: owner,
|
|
2399
|
-
amount: inputCompressedTokenAccounts.reduce(
|
|
2400
|
-
(sum, account) => sum.add(account.parsed.amount),
|
|
2401
|
-
new BN(0),
|
|
2402
|
-
),
|
|
2345
|
+
amount: inputCompressedTokenAccounts.reduce((sum, account) => sum.add(account.parsed.amount), new BN(0)),
|
|
2403
2346
|
outputStateTrees: outputStateTree,
|
|
2404
2347
|
recentInputStateRootIndices,
|
|
2405
2348
|
recentValidityProof,
|
|
@@ -2407,14 +2350,8 @@ class CompressedTokenProgram {
|
|
|
2407
2350
|
return [ix];
|
|
2408
2351
|
}
|
|
2409
2352
|
static async compressSplTokenAccount(params) {
|
|
2410
|
-
const {
|
|
2411
|
-
|
|
2412
|
-
authority,
|
|
2413
|
-
tokenAccount,
|
|
2414
|
-
mint,
|
|
2415
|
-
remainingAmount,
|
|
2416
|
-
outputStateTree,
|
|
2417
|
-
} = params;
|
|
2353
|
+
const { feePayer, authority, tokenAccount, mint, remainingAmount, outputStateTree, tokenProgramId, } = params;
|
|
2354
|
+
const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID;
|
|
2418
2355
|
const remainingAccountMetas = [
|
|
2419
2356
|
{
|
|
2420
2357
|
pubkey: outputStateTree,
|
|
@@ -2425,27 +2362,27 @@ class CompressedTokenProgram {
|
|
|
2425
2362
|
const instruction = await this.program.methods
|
|
2426
2363
|
.compressSplTokenAccount(authority, remainingAmount ?? null, null)
|
|
2427
2364
|
.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
|
-
})
|
|
2365
|
+
feePayer,
|
|
2366
|
+
authority,
|
|
2367
|
+
cpiAuthorityPda: this.deriveCpiAuthorityPda,
|
|
2368
|
+
lightSystemProgram: LightSystemProgram.programId,
|
|
2369
|
+
registeredProgramPda: defaultStaticAccountsStruct().registeredProgramPda,
|
|
2370
|
+
noopProgram: defaultStaticAccountsStruct().noopProgram,
|
|
2371
|
+
accountCompressionAuthority: defaultStaticAccountsStruct().accountCompressionAuthority,
|
|
2372
|
+
accountCompressionProgram: defaultStaticAccountsStruct().accountCompressionProgram,
|
|
2373
|
+
selfProgram: this.programId,
|
|
2374
|
+
tokenPoolPda: this.deriveTokenPoolPda(mint),
|
|
2375
|
+
compressOrDecompressTokenAccount: tokenAccount,
|
|
2376
|
+
tokenProgram,
|
|
2377
|
+
systemProgram: SystemProgram.programId,
|
|
2378
|
+
})
|
|
2445
2379
|
.remainingAccounts(remainingAccountMetas)
|
|
2446
2380
|
.instruction();
|
|
2447
2381
|
return instruction;
|
|
2448
2382
|
}
|
|
2383
|
+
static async get_mint_program_id(mint, connection) {
|
|
2384
|
+
return (await connection.getAccountInfo(mint))?.owner;
|
|
2385
|
+
}
|
|
2449
2386
|
}
|
|
2450
2387
|
|
|
2451
2388
|
/**
|
|
@@ -2463,22 +2400,11 @@ class CompressedTokenProgram {
|
|
|
2463
2400
|
*
|
|
2464
2401
|
* @return Signature of the confirmed transaction
|
|
2465
2402
|
*/
|
|
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
|
-
);
|
|
2403
|
+
async function approveAndMintTo(rpc, payer, mint, destination, authority, amount, merkleTree, confirmOptions, tokenProgramId) {
|
|
2404
|
+
tokenProgramId = tokenProgramId
|
|
2405
|
+
? tokenProgramId
|
|
2406
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2407
|
+
const authorityTokenAccount = await getOrCreateAssociatedTokenAccount(rpc, payer, mint, authority.publicKey, undefined, undefined, confirmOptions, tokenProgramId);
|
|
2482
2408
|
const ixs = await CompressedTokenProgram.approveAndMintTo({
|
|
2483
2409
|
feePayer: payer.publicKey,
|
|
2484
2410
|
mint,
|
|
@@ -2487,18 +2413,14 @@ async function approveAndMintTo(
|
|
|
2487
2413
|
amount,
|
|
2488
2414
|
toPubkey: destination,
|
|
2489
2415
|
merkleTree,
|
|
2416
|
+
tokenProgramId,
|
|
2490
2417
|
});
|
|
2491
2418
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2492
2419
|
const additionalSigners = dedupeSigner(payer, [authority]);
|
|
2493
|
-
const tx = buildAndSignTx(
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
],
|
|
2498
|
-
payer,
|
|
2499
|
-
blockhash,
|
|
2500
|
-
additionalSigners,
|
|
2501
|
-
);
|
|
2420
|
+
const tx = buildAndSignTx([
|
|
2421
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }),
|
|
2422
|
+
...ixs,
|
|
2423
|
+
], payer, blockhash, additionalSigners);
|
|
2502
2424
|
const txId = await sendAndConfirmTx(rpc, tx, confirmOptions);
|
|
2503
2425
|
return txId;
|
|
2504
2426
|
}
|
|
@@ -2521,17 +2443,10 @@ async function approveAndMintTo(
|
|
|
2521
2443
|
*
|
|
2522
2444
|
* @return Signature of the confirmed transaction
|
|
2523
2445
|
*/
|
|
2524
|
-
async function compress(
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
amount,
|
|
2529
|
-
owner,
|
|
2530
|
-
sourceTokenAccount,
|
|
2531
|
-
toAddress,
|
|
2532
|
-
merkleTree,
|
|
2533
|
-
confirmOptions,
|
|
2534
|
-
) {
|
|
2446
|
+
async function compress(rpc, payer, mint, amount, owner, sourceTokenAccount, toAddress, merkleTree, confirmOptions, tokenProgramId) {
|
|
2447
|
+
tokenProgramId = tokenProgramId
|
|
2448
|
+
? tokenProgramId
|
|
2449
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2535
2450
|
const compressIx = await CompressedTokenProgram.compress({
|
|
2536
2451
|
payer: payer.publicKey,
|
|
2537
2452
|
owner: owner.publicKey,
|
|
@@ -2540,26 +2455,17 @@ async function compress(
|
|
|
2540
2455
|
amount,
|
|
2541
2456
|
mint,
|
|
2542
2457
|
outputStateTree: merkleTree,
|
|
2458
|
+
tokenProgramId,
|
|
2543
2459
|
});
|
|
2544
2460
|
const blockhashCtx = await rpc.getLatestBlockhash();
|
|
2545
2461
|
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
|
-
);
|
|
2462
|
+
const signedTx = buildAndSignTx([
|
|
2463
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
2464
|
+
units: 1_000_000,
|
|
2465
|
+
}),
|
|
2466
|
+
compressIx,
|
|
2467
|
+
], payer, blockhashCtx.blockhash, additionalSigners);
|
|
2468
|
+
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions, blockhashCtx);
|
|
2563
2469
|
return txId;
|
|
2564
2470
|
}
|
|
2565
2471
|
|
|
@@ -2580,31 +2486,15 @@ async function compress(
|
|
|
2580
2486
|
*
|
|
2581
2487
|
* @return Signature of the confirmed transaction
|
|
2582
2488
|
*/
|
|
2583
|
-
async function transfer(
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
mint,
|
|
2587
|
-
amount,
|
|
2588
|
-
owner,
|
|
2589
|
-
toAddress,
|
|
2590
|
-
/// TODO: allow multiple
|
|
2591
|
-
merkleTree,
|
|
2592
|
-
confirmOptions,
|
|
2593
|
-
) {
|
|
2489
|
+
async function transfer(rpc, payer, mint, amount, owner, toAddress,
|
|
2490
|
+
/// TODO: allow multiple
|
|
2491
|
+
merkleTree, confirmOptions) {
|
|
2594
2492
|
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
|
-
);
|
|
2493
|
+
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(owner.publicKey, {
|
|
2494
|
+
mint,
|
|
2495
|
+
});
|
|
2496
|
+
const [inputAccounts] = selectMinCompressedTokenAccountsForTransfer(compressedTokenAccounts.items, amount);
|
|
2497
|
+
const proof = await rpc.getValidityProof(inputAccounts.map(account => bn(account.compressedAccount.hash)));
|
|
2608
2498
|
const ix = await CompressedTokenProgram.transfer({
|
|
2609
2499
|
payer: payer.publicKey,
|
|
2610
2500
|
inputCompressedTokenAccounts: inputAccounts,
|
|
@@ -2616,12 +2506,7 @@ async function transfer(
|
|
|
2616
2506
|
});
|
|
2617
2507
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2618
2508
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2619
|
-
const signedTx = buildAndSignTx(
|
|
2620
|
-
[ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix],
|
|
2621
|
-
payer,
|
|
2622
|
-
blockhash,
|
|
2623
|
-
additionalSigners,
|
|
2624
|
-
);
|
|
2509
|
+
const signedTx = buildAndSignTx([ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix], payer, blockhash, additionalSigners);
|
|
2625
2510
|
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions);
|
|
2626
2511
|
return txId;
|
|
2627
2512
|
}
|
|
@@ -2638,17 +2523,14 @@ function selectMinCompressedTokenAccountsForTransfer(accounts, transferAmount) {
|
|
|
2638
2523
|
const selectedAccounts = [];
|
|
2639
2524
|
accounts.sort((a, b) => b.parsed.amount.cmp(a.parsed.amount));
|
|
2640
2525
|
for (const account of accounts) {
|
|
2641
|
-
if (accumulatedAmount.gte(bn(transferAmount)))
|
|
2526
|
+
if (accumulatedAmount.gte(bn(transferAmount)))
|
|
2527
|
+
break;
|
|
2642
2528
|
accumulatedAmount = accumulatedAmount.add(account.parsed.amount);
|
|
2643
|
-
accumulatedLamports = accumulatedLamports.add(
|
|
2644
|
-
account.compressedAccount.lamports,
|
|
2645
|
-
);
|
|
2529
|
+
accumulatedLamports = accumulatedLamports.add(account.compressedAccount.lamports);
|
|
2646
2530
|
selectedAccounts.push(account);
|
|
2647
2531
|
}
|
|
2648
2532
|
if (accumulatedAmount.lt(bn(transferAmount))) {
|
|
2649
|
-
throw new Error(
|
|
2650
|
-
`Not enough balance for transfer. Required: ${transferAmount.toString()}, available: ${accumulatedAmount.toString()}`,
|
|
2651
|
-
);
|
|
2533
|
+
throw new Error(`Not enough balance for transfer. Required: ${transferAmount.toString()}, available: ${accumulatedAmount.toString()}`);
|
|
2652
2534
|
}
|
|
2653
2535
|
return [
|
|
2654
2536
|
selectedAccounts,
|
|
@@ -2675,32 +2557,19 @@ function selectMinCompressedTokenAccountsForTransfer(accounts, transferAmount) {
|
|
|
2675
2557
|
*
|
|
2676
2558
|
* @return Signature of the confirmed transaction
|
|
2677
2559
|
*/
|
|
2678
|
-
async function decompress(
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
toAddress,
|
|
2685
|
-
/// TODO: allow multiple
|
|
2686
|
-
merkleTree,
|
|
2687
|
-
confirmOptions,
|
|
2688
|
-
) {
|
|
2560
|
+
async function decompress(rpc, payer, mint, amount, owner, toAddress,
|
|
2561
|
+
/// TODO: allow multiple
|
|
2562
|
+
merkleTree, confirmOptions, tokenProgramId) {
|
|
2563
|
+
tokenProgramId = tokenProgramId
|
|
2564
|
+
? tokenProgramId
|
|
2565
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2689
2566
|
amount = bn(amount);
|
|
2690
|
-
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
mint,
|
|
2694
|
-
},
|
|
2695
|
-
);
|
|
2567
|
+
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(owner.publicKey, {
|
|
2568
|
+
mint,
|
|
2569
|
+
});
|
|
2696
2570
|
/// 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
|
-
);
|
|
2571
|
+
const [inputAccounts] = selectMinCompressedTokenAccountsForTransfer(compressedTokenAccounts.items, amount);
|
|
2572
|
+
const proof = await rpc.getValidityProof(inputAccounts.map(account => bn(account.compressedAccount.hash)));
|
|
2704
2573
|
const ix = await CompressedTokenProgram.decompress({
|
|
2705
2574
|
payer: payer.publicKey,
|
|
2706
2575
|
inputCompressedTokenAccounts: inputAccounts,
|
|
@@ -2709,15 +2578,11 @@ async function decompress(
|
|
|
2709
2578
|
outputStateTree: merkleTree,
|
|
2710
2579
|
recentInputStateRootIndices: proof.rootIndices,
|
|
2711
2580
|
recentValidityProof: proof.compressedProof,
|
|
2581
|
+
tokenProgramId,
|
|
2712
2582
|
});
|
|
2713
2583
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2714
2584
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2715
|
-
const signedTx = buildAndSignTx(
|
|
2716
|
-
[ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix],
|
|
2717
|
-
payer,
|
|
2718
|
-
blockhash,
|
|
2719
|
-
additionalSigners,
|
|
2720
|
-
);
|
|
2585
|
+
const signedTx = buildAndSignTx([ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix], payer, blockhash, additionalSigners);
|
|
2721
2586
|
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions);
|
|
2722
2587
|
return txId;
|
|
2723
2588
|
}
|
|
@@ -2731,19 +2596,13 @@ async function decompress(
|
|
|
2731
2596
|
* @param decimals Location of the decimal place
|
|
2732
2597
|
* @param keypair Optional keypair, defaulting to a new random one
|
|
2733
2598
|
* @param confirmOptions Options for confirming the transaction
|
|
2599
|
+
* @param isToken22 Whether to create a Token 2022 mint. Defaults to false.
|
|
2734
2600
|
*
|
|
2735
2601
|
* @return Address of the new mint and the transaction signature
|
|
2736
2602
|
*/
|
|
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);
|
|
2603
|
+
async function createMint(rpc, payer, mintAuthority, decimals, keypair = Keypair.generate(), confirmOptions, isToken22 = false) {
|
|
2604
|
+
const rentExemptBalance = await rpc.getMinimumBalanceForRentExemption(MINT_SIZE);
|
|
2605
|
+
const tokenProgramId = isToken22 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID;
|
|
2747
2606
|
const ixs = await CompressedTokenProgram.createMint({
|
|
2748
2607
|
feePayer: payer.publicKey,
|
|
2749
2608
|
mint: keypair.publicKey,
|
|
@@ -2751,6 +2610,7 @@ async function createMint(
|
|
|
2751
2610
|
authority: mintAuthority,
|
|
2752
2611
|
freezeAuthority: null, // TODO: add feature
|
|
2753
2612
|
rentExemptBalance,
|
|
2613
|
+
tokenProgramId,
|
|
2754
2614
|
});
|
|
2755
2615
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2756
2616
|
const additionalSigners = dedupeSigner(payer, [keypair]);
|
|
@@ -2776,16 +2636,10 @@ async function createMint(
|
|
|
2776
2636
|
*
|
|
2777
2637
|
* @return Signature of the confirmed transaction
|
|
2778
2638
|
*/
|
|
2779
|
-
async function mintTo(
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
destination,
|
|
2784
|
-
authority,
|
|
2785
|
-
amount,
|
|
2786
|
-
merkleTree,
|
|
2787
|
-
confirmOptions,
|
|
2788
|
-
) {
|
|
2639
|
+
async function mintTo(rpc, payer, mint, destination, authority, amount, merkleTree, confirmOptions, tokenProgramId) {
|
|
2640
|
+
tokenProgramId = tokenProgramId
|
|
2641
|
+
? tokenProgramId
|
|
2642
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2789
2643
|
const additionalSigners = dedupeSigner(payer, [authority]);
|
|
2790
2644
|
const ix = await CompressedTokenProgram.mintTo({
|
|
2791
2645
|
feePayer: payer.publicKey,
|
|
@@ -2794,14 +2648,10 @@ async function mintTo(
|
|
|
2794
2648
|
amount: amount,
|
|
2795
2649
|
toPubkey: destination,
|
|
2796
2650
|
merkleTree,
|
|
2651
|
+
tokenProgramId,
|
|
2797
2652
|
});
|
|
2798
2653
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2799
|
-
const tx = buildAndSignTx(
|
|
2800
|
-
[ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix],
|
|
2801
|
-
payer,
|
|
2802
|
-
blockhash,
|
|
2803
|
-
additionalSigners,
|
|
2804
|
-
);
|
|
2654
|
+
const tx = buildAndSignTx([ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }), ix], payer, blockhash, additionalSigners);
|
|
2805
2655
|
const txId = await sendAndConfirmTx(rpc, tx, confirmOptions);
|
|
2806
2656
|
return txId;
|
|
2807
2657
|
}
|
|
@@ -2819,60 +2669,34 @@ async function mintTo(
|
|
|
2819
2669
|
*
|
|
2820
2670
|
* @return Array of transaction signatures
|
|
2821
2671
|
*/
|
|
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
|
-
);
|
|
2672
|
+
async function mergeTokenAccounts(rpc, payer, mint, owner, merkleTree, confirmOptions) {
|
|
2673
|
+
const compressedTokenAccounts = await rpc.getCompressedTokenAccountsByOwner(owner.publicKey, { mint });
|
|
2834
2674
|
if (compressedTokenAccounts.items.length === 0) {
|
|
2835
|
-
throw new Error(
|
|
2836
|
-
`No compressed token accounts found for mint ${mint.toBase58()}`,
|
|
2837
|
-
);
|
|
2675
|
+
throw new Error(`No compressed token accounts found for mint ${mint.toBase58()}`);
|
|
2838
2676
|
}
|
|
2839
2677
|
if (compressedTokenAccounts.items.length >= 6) {
|
|
2840
|
-
throw new Error(
|
|
2841
|
-
`Too many compressed token accounts used for mint ${mint.toBase58()}`,
|
|
2842
|
-
);
|
|
2678
|
+
throw new Error(`Too many compressed token accounts used for mint ${mint.toBase58()}`);
|
|
2843
2679
|
}
|
|
2844
2680
|
const instructions = [
|
|
2845
2681
|
ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }),
|
|
2846
2682
|
];
|
|
2847
|
-
for (
|
|
2848
|
-
let i = 0;
|
|
2849
|
-
i < compressedTokenAccounts.items.slice(0, 6).length;
|
|
2850
|
-
i += 3
|
|
2851
|
-
) {
|
|
2683
|
+
for (let i = 0; i < compressedTokenAccounts.items.slice(0, 6).length; i += 3) {
|
|
2852
2684
|
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
|
-
});
|
|
2685
|
+
const proof = await rpc.getValidityProof(batch.map(account => bn(account.compressedAccount.hash)));
|
|
2686
|
+
const batchInstructions = await CompressedTokenProgram.mergeTokenAccounts({
|
|
2687
|
+
payer: payer.publicKey,
|
|
2688
|
+
owner: owner.publicKey,
|
|
2689
|
+
mint,
|
|
2690
|
+
inputCompressedTokenAccounts: batch,
|
|
2691
|
+
outputStateTree: merkleTree,
|
|
2692
|
+
recentValidityProof: proof.compressedProof,
|
|
2693
|
+
recentInputStateRootIndices: proof.rootIndices,
|
|
2694
|
+
});
|
|
2866
2695
|
instructions.push(...batchInstructions);
|
|
2867
2696
|
}
|
|
2868
2697
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2869
2698
|
const additionalSigners = dedupeSigner(payer, [owner]);
|
|
2870
|
-
const signedTx = buildAndSignTx(
|
|
2871
|
-
instructions,
|
|
2872
|
-
payer,
|
|
2873
|
-
blockhash,
|
|
2874
|
-
additionalSigners,
|
|
2875
|
-
);
|
|
2699
|
+
const signedTx = buildAndSignTx(instructions, payer, blockhash, additionalSigners);
|
|
2876
2700
|
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions);
|
|
2877
2701
|
return txId;
|
|
2878
2702
|
}
|
|
@@ -2888,10 +2712,14 @@ async function mergeTokenAccounts(
|
|
|
2888
2712
|
*
|
|
2889
2713
|
* @return transaction signature
|
|
2890
2714
|
*/
|
|
2891
|
-
async function createTokenPool(rpc, payer,
|
|
2715
|
+
async function createTokenPool(rpc, payer, mint, confirmOptions, tokenProgramId) {
|
|
2716
|
+
tokenProgramId = tokenProgramId
|
|
2717
|
+
? tokenProgramId
|
|
2718
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2892
2719
|
const ix = await CompressedTokenProgram.createTokenPool({
|
|
2893
2720
|
feePayer: payer.publicKey,
|
|
2894
|
-
mint
|
|
2721
|
+
mint,
|
|
2722
|
+
tokenProgramId,
|
|
2895
2723
|
});
|
|
2896
2724
|
const { blockhash } = await rpc.getLatestBlockhash();
|
|
2897
2725
|
const tx = buildAndSignTx([ix], payer, blockhash);
|
|
@@ -2912,50 +2740,23 @@ async function createTokenPool(rpc, payer, mintAddress, confirmOptions) {
|
|
|
2912
2740
|
*
|
|
2913
2741
|
* @return Transaction signatures and the address of the created lookup table
|
|
2914
2742
|
*/
|
|
2915
|
-
async function createTokenProgramLookupTable(
|
|
2916
|
-
rpc,
|
|
2917
|
-
payer,
|
|
2918
|
-
authority,
|
|
2919
|
-
mints,
|
|
2920
|
-
additionalAccounts,
|
|
2921
|
-
) {
|
|
2743
|
+
async function createTokenProgramLookupTable(rpc, payer, authority, mints, additionalAccounts) {
|
|
2922
2744
|
const recentSlot = await rpc.getSlot('finalized');
|
|
2923
|
-
const { instructions, address } =
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
});
|
|
2745
|
+
const { instructions, address } = await CompressedTokenProgram.createTokenProgramLookupTable({
|
|
2746
|
+
payer: payer.publicKey,
|
|
2747
|
+
authority: authority.publicKey,
|
|
2748
|
+
mints,
|
|
2749
|
+
remainingAccounts: additionalAccounts,
|
|
2750
|
+
recentSlot,
|
|
2751
|
+
});
|
|
2931
2752
|
const additionalSigners = dedupeSigner(payer, [authority]);
|
|
2932
2753
|
const blockhashCtx = await rpc.getLatestBlockhash();
|
|
2933
|
-
const signedTx = buildAndSignTx(
|
|
2934
|
-
[instructions[0]],
|
|
2935
|
-
payer,
|
|
2936
|
-
blockhashCtx.blockhash,
|
|
2937
|
-
additionalSigners,
|
|
2938
|
-
);
|
|
2754
|
+
const signedTx = buildAndSignTx([instructions[0]], payer, blockhashCtx.blockhash, additionalSigners);
|
|
2939
2755
|
/// Must wait for the first instruction to be finalized.
|
|
2940
|
-
const txId = await sendAndConfirmTx(
|
|
2941
|
-
rpc,
|
|
2942
|
-
signedTx,
|
|
2943
|
-
{ commitment: 'finalized' },
|
|
2944
|
-
blockhashCtx,
|
|
2945
|
-
);
|
|
2756
|
+
const txId = await sendAndConfirmTx(rpc, signedTx, { commitment: 'finalized' }, blockhashCtx);
|
|
2946
2757
|
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
|
-
);
|
|
2758
|
+
const signedTx2 = buildAndSignTx([instructions[1]], payer, blockhashCtx2.blockhash, additionalSigners);
|
|
2759
|
+
const txId2 = await sendAndConfirmTx(rpc, signedTx2, { commitment: 'finalized' }, blockhashCtx2);
|
|
2959
2760
|
return { txIds: [txId, txId2], address };
|
|
2960
2761
|
}
|
|
2961
2762
|
|
|
@@ -2973,16 +2774,10 @@ async function createTokenProgramLookupTable(
|
|
|
2973
2774
|
*
|
|
2974
2775
|
* @return Signature of the confirmed transaction
|
|
2975
2776
|
*/
|
|
2976
|
-
async function compressSplTokenAccount(
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
owner,
|
|
2981
|
-
tokenAccount,
|
|
2982
|
-
outputStateTree,
|
|
2983
|
-
remainingAmount,
|
|
2984
|
-
confirmOptions,
|
|
2985
|
-
) {
|
|
2777
|
+
async function compressSplTokenAccount(rpc, payer, mint, owner, tokenAccount, outputStateTree, remainingAmount, confirmOptions, tokenProgramId) {
|
|
2778
|
+
tokenProgramId = tokenProgramId
|
|
2779
|
+
? tokenProgramId
|
|
2780
|
+
: await CompressedTokenProgram.get_mint_program_id(mint, rpc);
|
|
2986
2781
|
const compressIx = await CompressedTokenProgram.compressSplTokenAccount({
|
|
2987
2782
|
feePayer: payer.publicKey,
|
|
2988
2783
|
authority: owner.publicKey,
|
|
@@ -2990,51 +2785,19 @@ async function compressSplTokenAccount(
|
|
|
2990
2785
|
mint,
|
|
2991
2786
|
remainingAmount,
|
|
2992
2787
|
outputStateTree,
|
|
2788
|
+
tokenProgramId,
|
|
2993
2789
|
});
|
|
2994
2790
|
const blockhashCtx = await rpc.getLatestBlockhash();
|
|
2995
2791
|
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
|
-
);
|
|
2792
|
+
const signedTx = buildAndSignTx([
|
|
2793
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
2794
|
+
units: 1_000_000,
|
|
2795
|
+
}),
|
|
2796
|
+
compressIx,
|
|
2797
|
+
], payer, blockhashCtx.blockhash, additionalSigners);
|
|
2798
|
+
const txId = await sendAndConfirmTx(rpc, signedTx, confirmOptions, blockhashCtx);
|
|
3013
2799
|
return txId;
|
|
3014
2800
|
}
|
|
3015
2801
|
|
|
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
|
-
};
|
|
2802
|
+
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
2803
|
//# sourceMappingURL=index.js.map
|