|
| 1 | +--- |
| 2 | +title: Example usage of the TS SDK |
| 3 | +--- |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +## Install |
| 8 | + |
| 9 | +```shell |
| 10 | +npm install --save @solana/spl-account-compression @solana/web3.js |
| 11 | +``` |
| 12 | + |
| 13 | +__OR__ |
| 14 | + |
| 15 | +```shell |
| 16 | +yarn add @solana/spl-account-compression @solana/web3.js |
| 17 | +``` |
| 18 | + |
| 19 | +### Examples |
| 20 | + |
| 21 | +1. Create a tree |
| 22 | + |
| 23 | +```typescript |
| 24 | +// Assume: known `payer` Keypair |
| 25 | +// Generate a keypair for the ConcurrentMerkleTree |
| 26 | +const cmtKeypair = Keypair.generate(); |
| 27 | +// Create a system instruction to allocate enough |
| 28 | +// space for the tree |
| 29 | +const allocAccountIx = await createAllocTreeIx( |
| 30 | + connection, |
| 31 | + cmtKeypair.publicKey, |
| 32 | + payer.publicKey, |
| 33 | + { maxDepth, maxBufferSize }, |
| 34 | + canopyDepth, |
| 35 | +); |
| 36 | +// Create an SPL compression instruction to initialize |
| 37 | +// the newly created ConcurrentMerkleTree |
| 38 | +const initTreeIx = createInitEmptyMerkleTreeIx( |
| 39 | + cmtKeypair.publicKey, |
| 40 | + payer.publicKey, |
| 41 | + { maxDepth, maxBufferSize } |
| 42 | +); |
| 43 | +const tx = new Transaction().add(allocAccountIx).add(initTreeIx); |
| 44 | +await sendAndConfirmTransaction(connection, tx, [cmtKeypair, payer]); |
| 45 | +``` |
| 46 | + |
| 47 | +2. Add a leaf to the tree |
| 48 | + |
| 49 | +```typescript |
| 50 | +// Create a new leaf |
| 51 | +const newLeaf: Buffer = crypto.randomBytes(32); |
| 52 | +// Add the new leaf to the existing tree |
| 53 | +const appendIx = createAppendIx(cmtKeypair.publicKey, payer.publicKey, newLeaf); |
| 54 | +const tx = new Transaction().add(appendIx); |
| 55 | +await sendAndConfirmTransaction(connection, tx, [payer]); |
| 56 | +``` |
| 57 | + |
| 58 | +3. Replace a leaf in the tree, using the provided `MerkleTree` as an indexer |
| 59 | + |
| 60 | +This example assumes that `offChainTree` has been indexing all previous modifying transactions |
| 61 | +involving this tree. |
| 62 | +It is okay for the indexer to be behind by a maximum of `maxBufferSize` transactions. |
| 63 | + |
| 64 | + |
| 65 | +```typescript |
| 66 | +// Assume: `offChainTree` is a MerkleTree instance |
| 67 | +// that has been indexing the `cmtKeypair.publicKey` transactions |
| 68 | +// Get a new leaf |
| 69 | +const newLeaf: Buffer = crypto.randomBytes(32); |
| 70 | +// Query off-chain records for information about the leaf |
| 71 | +// you wish to replace by its index in the tree |
| 72 | +const leafIndex = 314; |
| 73 | +// Replace the leaf at `leafIndex` with `newLeaf` |
| 74 | +const replaceIx = createReplaceIx( |
| 75 | + cmtKeypair.publicKey, |
| 76 | + payer.publicKey, |
| 77 | + newLeaf, |
| 78 | + offChainTree.getProof(leafIndex) |
| 79 | +); |
| 80 | +const tx = new Transaction().add(replaceIx); |
| 81 | +await sendAndConfirmTransaction(connection, tx, [payer]); |
| 82 | +``` |
| 83 | + |
| 84 | +4. Replace a leaf in the tree, using a 3rd party indexer |
| 85 | + |
| 86 | +This example assumes that some 3rd party service is indexing the the tree at `cmtKeypair.publicKey` for you, and providing MerkleProofs via some REST endpoint. |
| 87 | +The `getProofFromAnIndexer` function is a **placeholder** to exemplify this relationship. |
| 88 | + |
| 89 | +```typescript |
| 90 | +// Get a new leaf |
| 91 | +const newLeaf: Buffer = crypto.randomBytes(32); |
| 92 | +// Query off-chain indexer for a MerkleProof |
| 93 | +// possibly by executing GET request against a REST api |
| 94 | +const proof = await getProofFromAnIndexer(myOldLeaf); |
| 95 | +// Replace `myOldLeaf` with `newLeaf` at the same index in the tree |
| 96 | +const replaceIx = createReplaceIx( |
| 97 | + cmtKeypair.publicKey, |
| 98 | + payer.publicKey, |
| 99 | + newLeaf, |
| 100 | + proof |
| 101 | +); |
| 102 | +const tx = new Transaction().add(replaceIx); |
| 103 | +await sendAndConfirmTransaction(connection, tx, [payer]); |
| 104 | +``` |
| 105 | + |
| 106 | +## Reference examples |
| 107 | + |
| 108 | +Here are some examples using account compression in the wild: |
| 109 | + |
| 110 | +* Solana Program Library [tests](https://github.com/solana-labs/solana-program-library/tree/master/account-compression/sdk/tests) |
| 111 | + |
| 112 | +* Metaplex Program Library Compressed NFT [tests](https://github.com/metaplex-foundation/metaplex-program-library/tree/master/bubblegum/js/tests) |
0 commit comments