├── .env.sample ├── .gitignore ├── .prettierrc ├── README.md ├── img ├── Whaler_logo.gif ├── Whaler_logo.png └── avator.png ├── package-lock.json ├── package.json ├── scripts ├── 1.Account │ ├── 1.Keypair.ts │ ├── 2.LuckyAccount.ts │ └── 3.Payer.ts ├── 2.VersionedTx │ ├── 1.SendSimpleTx.ts │ ├── 2.SendComplexTx.ts │ ├── CreateAccountIx.ts │ ├── CreateVersionedTx.ts │ ├── MinimumBalanceForRentExemption.ts │ ├── SendVersionedTx.ts │ ├── SignTx.ts │ └── Transfer.ts ├── 3.Token │ ├── 1.CreateMint.ts │ ├── 2.MintTokens.ts │ ├── 3.Burn.ts │ ├── 4.BurnAll.ts │ ├── 5.GetTokenAccountsByOwner.ts │ ├── 6.Transfer.ts │ ├── 7.NonFungibleToken.ts │ ├── ATA.ts │ ├── Burn.ts │ ├── CloseAccount.ts │ ├── CreateMint.ts │ ├── CreateSetAuthorityInstyIx.ts │ ├── MintTo.ts │ └── TransferToken.ts ├── 4.WrapSOL │ ├── 1.WrapSOL.ts │ ├── 2.UnWrapSOL.ts │ ├── AddTransaction.ts │ ├── CloseAccount.ts │ ├── CreateSyncNativeIx.ts │ └── SendAndConfirmTx.ts ├── 5.UmiTokenMetadata │ ├── 1.TokenStandards │ │ └── TokenStandard.ts │ ├── 10.DelegatedAuthorities │ │ ├── 1.AuthorityItemDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Update.ts │ │ ├── 10.TransferDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Transfer.ts │ │ ├── 11.LockedTransferDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ ├── 3.Transfer.ts │ │ │ ├── 4.Lock.ts │ │ │ └── 5.Unlock.ts │ │ ├── 12.UtilityDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ ├── 3.Burn.ts │ │ │ ├── 4.Lock.ts │ │ │ └── 5.Unlock.ts │ │ ├── 13.StakingDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ ├── 3.Lock.ts │ │ │ └── 4.Unlock.ts │ │ ├── 2.CollectionDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Update.ts │ │ ├── 3.CollectionItemDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Update.ts │ │ ├── 4.DataDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Update.ts │ │ ├── 5.DataItemDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Update.ts │ │ ├── 6.ProgrammableConfigDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Update.ts │ │ ├── 7.ProgrammableConfigItemDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Update.ts │ │ ├── 8.StandardDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ ├── 3.Transfer.ts │ │ │ ├── 4.Burn.ts │ │ │ ├── 5.Lock.ts │ │ │ └── 6.Unlock.ts │ │ └── 9.SaleDelegate │ │ │ ├── 1.Approve.ts │ │ │ ├── 2.Revoke.ts │ │ │ └── 3.Transfer.ts │ ├── 2.MintingAssets │ │ ├── 1.UploadMetadata.ts │ │ ├── 2.Create.ts │ │ ├── 3.Mint.ts │ │ ├── 4.CreateNonFungible.ts │ │ ├── 5.CreateFungible.ts │ │ ├── 6.CreateFungibleAsset.ts │ │ └── 7.CreateProgrammableNft.ts │ ├── 3.FetchingAssets │ │ ├── 1.FetchDigitalAsset.ts │ │ ├── 10.FetchAllDigitalAssetWithTokenByMint.ts │ │ ├── 11.FetchAllDigitalAssetWithTokenByOwnerAndMint.ts │ │ ├── 2.FetchDigitalAssetByMetadata.ts │ │ ├── 3.FetchAllDigitalAsset.ts │ │ ├── 4.FetchAllDigitalAssetByCreator.ts │ │ ├── 5.FetchAllDigitalAssetByOwner.ts │ │ ├── 6.FetchAllDigitalAssetByUpdateAuthority.ts │ │ ├── 7.FetchDigitalAssetWithTokenByMint.ts │ │ ├── 8.FetchDigitalAssetWithAssociatedToken.ts │ │ └── 9.FetchAllDigitalAssetWithTokenByOwner.ts │ ├── 4.UpdatingAssets │ │ └── 1.UpdateTokenMetadata.ts │ ├── 5.TransferringAssets │ │ └── 1.Transfer.ts │ ├── 6.BurningAssets │ │ └── 1.Burn.ts │ ├── 7.PrintedEditions │ │ └── 1.Print.ts │ ├── 8.VerifiedCollections │ │ ├── 0.CreateCollection.ts │ │ ├── 1.CreateCollectionNFT.ts │ │ ├── 2.VerifyCollection.ts │ │ └── 3.UnVerifyCollection.ts │ └── 9.VerifiedCreators │ │ ├── 1.VerifyCreator.ts │ │ └── 2.UnVerifyCreator.ts └── lib │ ├── helpers.ts │ ├── umiHelper.ts │ └── vars.ts ├── tsconfig.json ├── yarn-error.log └── yarn.lock /.env.sample: -------------------------------------------------------------------------------- 1 | RPC_URL='' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .local_keys 4 | package-lock.json 5 | yarn-error.log 6 | yarn.lock 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "singleQuote": false, 5 | "printWidth": 100, 6 | "trailingComma": "all", 7 | "arrowParens": "avoid", 8 | "endOfLine": "auto", 9 | "proseWrap": "always" 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solana 编程第一章 基础编程 2 | ### 安装 3 | 1. 安装Solana客户端 4 | 详细安装文档: 5 | https://docs.solanalabs.com/cli/install 6 | ``` 7 | sh -c "$(curl -sSfL https://release.solana.com/v1.18.4/install)" 8 | solana --version 9 | ``` 10 | 2. 安装Rust https://rustup.rs/ 11 | ``` 12 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 13 | ``` 14 | 3. 安装SPL客户端 15 | ``` 16 | cargo install spl-token-cli 17 | ``` 18 | 4. 配置RPC节点 19 | - 查询当前配置 20 | ``` 21 | $ solana config get 22 | Config File: ${HOME}/.config/solana/cli/config.yml 23 | RPC URL: https://api.mainnet-beta.solana.com 24 | WebSocket URL: wss://api.mainnet-beta.solana.com/ (computed) 25 | Keypair Path: ${HOME}/.config/solana/id.json 26 | ``` 27 | - 设置RPC节点地址 28 | ``` 29 | solana config set --url https://api.devnet.solana.com 30 | ``` 31 | 5. 克隆教学仓库 32 | ``` 33 | git clone https://github.com/Fankouzu/solana-basic.git 34 | npm install 35 | ``` 36 | ------------ 37 | ## 第一章 基础编程 38 | 39 | ### 1. 创建密钥对 40 | - JS 41 | ``` 42 | npm run demo scripts/1.Keypair.ts 43 | ``` 44 | - CLI 45 | ``` 46 | solana-keygen pubkey 47 | ``` 48 | 49 | ### 2. 幸运账号 50 | ``` 51 | npm run demo scripts/2.LuckyAccount.ts 52 | ``` 53 | 54 | ### 3. 创建支付账号 55 | ``` 56 | npm run demo scripts/3.Payer.ts 57 | ``` 58 | ### 4. 获取最小租金豁免数额 59 | [./scripts/4.MinimumBalanceForRentExemption.ts](./scripts/4.MinimumBalanceForRentExemption.ts) 60 | ### 5. 创建账号IX 61 | [./scripts/5.CreateAccountIx.ts](./scripts/5.CreateAccountIx.ts) 62 | ### 6. 创建发送交易 63 | [./scripts/6.Transfer.ts](./scripts/6.Transfer.ts) 64 | ### 7. 创建版本化交易 65 | [./scripts/7.CreateVersionedTx.ts](./scripts/7.CreateVersionedTx.ts) 66 | ### 8. 签署交易 67 | [./scripts/8.SignTx.ts](./scripts/8.SignTx.ts) 68 | ### 9. 发送交易 69 | [./scripts/8.SendTx.ts](./scripts/9.SendTx.ts) 70 | ### 10. 发送简单交易 71 | ``` 72 | npm run demo scripts/10.SendSimpleTx.ts 73 | ``` 74 | ### 11. 发送复杂交易 75 | ``` 76 | npm run demo scripts/11.SendComplexTx.ts 77 | ``` 78 | ### 12. 创建Token 79 | ``` 80 | npm run demo scripts/12.CreateMint.ts 81 | ``` 82 | ### 13. ATA账户 83 | [./scripts/13.ATA.ts](./scripts/13.ATA.ts) 84 | ### 14. 铸造Token 85 | ``` 86 | npm run demo scripts/14.MintTokens.ts 87 | ``` 88 | ### Token Cli 89 | 1. 创建Token 90 | ``` 91 | spl-token create-token 92 | ``` 93 | 2. 查询总量 94 | ``` 95 | spl-token supply AQoKYV7tYpTrFZN6P5oUufbQKAUr9mNYGe1TTJC9wajM 96 | ``` 97 | 3. 创建账户 98 | ``` 99 | spl-token create-account AQoKYV7tYpTrFZN6P5oUufbQKAUr9mNYGe1TTJC9wajM 100 | ``` 101 | 4. 查询余额 102 | ``` 103 | spl-token balance AQoKYV7tYpTrFZN6P5oUufbQKAUr9mNYGe1TTJC9wajM 104 | ``` 105 | 5. 铸造Token 106 | ``` 107 | spl-token mint AQoKYV7tYpTrFZN6P5oUufbQKAUr9mNYGe1TTJC9wajM 100 108 | ``` 109 | 110 | 111 | ### 15. 查询账户下所有Token 112 | ``` 113 | npm run demo scripts/15.GetTokenAccountsByOwner.ts 114 | ``` 115 | ### 16. 包装SOL 116 | 117 | ### 17. 解包装SOL 118 | 119 | ### 18. 发送Token 120 | 121 | ### 19. 创建NFT 122 | 123 | ### 20. 多签用例 124 | 125 | ### 21. 使用多签铸造Token 126 | 127 | ### 22. 离线签名 128 | 129 | # Solana编程第二章 高级Token应用 130 | ### FT 131 | ### NFT 132 | # Solana编程第三章 Defi应用 133 | ### Swap交易所 134 | ### Lending借贷平台 135 | ### Staking质押 -------------------------------------------------------------------------------- /img/Whaler_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whaler-academy/solana-basic/76129a3da580668bfb1658e834b77ff65b495b31/img/Whaler_logo.gif -------------------------------------------------------------------------------- /img/Whaler_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whaler-academy/solana-basic/76129a3da580668bfb1658e834b77ff65b495b31/img/Whaler_logo.png -------------------------------------------------------------------------------- /img/avator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whaler-academy/solana-basic/76129a3da580668bfb1658e834b77ff65b495b31/img/avator.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solana-basic", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "demo": "npx ts-node", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@metaplex-foundation/mpl-bubblegum": "^4.0.0", 14 | "@metaplex-foundation/mpl-candy-machine": "^6.0.1", 15 | "@metaplex-foundation/mpl-token-metadata": "^3.2.1", 16 | "@metaplex-foundation/umi": "^0.9.1", 17 | "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", 18 | "@metaplex-foundation/umi-uploader-irys": "^0.9.1", 19 | "@project-serum/anchor": "^0.26.0", 20 | "@solana/spl-token": "^0.3.7", 21 | "@solana/web3.js": "^1.91.7", 22 | "bs58": "^5.0.0", 23 | "dotenv": "^16.0.3" 24 | }, 25 | "devDependencies": { 26 | "eslint": "^8.35.0", 27 | "ts-node": "^10.9.1", 28 | "tsconfig-paths": "^4.1.2", 29 | "typescript": "^4.8.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /scripts/1.Account/1.Keypair.ts: -------------------------------------------------------------------------------- 1 | import { Keypair } from "@solana/web3.js"; 2 | import base58 from "bs58"; 3 | import { FgGreen, FgYellow } from "../lib/vars"; 4 | 5 | // 创建Keypair 6 | (async () => { 7 | // 随机创建Keypair 8 | let keypair = Keypair.generate(); 9 | console.log(`${FgGreen}publicKey 公钥/地址: ${FgYellow + keypair.publicKey.toBase58()}`); 10 | console.log(`${FgGreen}secretKey 私钥: ${FgYellow}[${keypair.secretKey}]`); 11 | console.log(`${FgGreen}secretKey 私钥-Base58: ${FgYellow + base58.encode(keypair.secretKey)}`); 12 | })(); 13 | -------------------------------------------------------------------------------- /scripts/1.Account/2.LuckyAccount.ts: -------------------------------------------------------------------------------- 1 | import { Keypair } from "@solana/web3.js"; 2 | import { FgGreen, FgRed, FgYellow } from "../lib/vars"; 3 | 4 | // 幸运账号 5 | const luckyStr = "Cui"; // 自定义前缀 6 | (async () => { 7 | let count = 0; 8 | let retry = 0; 9 | // 循环直到找到50个幸运账号 10 | while (count < 50) { 11 | // 随机Keypair 12 | let keypair = Keypair.generate(); 13 | if (keypair.publicKey.toString().startsWith(luckyStr)) { 14 | process.stdout.clearLine(0); 15 | process.stdout.cursorTo(0); 16 | console.log(`${FgGreen}Found 公钥/地址: ${FgYellow + keypair.publicKey.toBase58()}`); 17 | console.log(`${FgGreen}Found 私钥: ${FgYellow}[${keypair.secretKey}]`); 18 | count++; 19 | } else { 20 | process.stdout.clearLine(0); 21 | process.stdout.cursorTo(0); 22 | process.stdout.write(`${FgRed}${keypair.publicKey.toString()} ${retry}`); 23 | retry++; 24 | } 25 | } 26 | })(); 27 | -------------------------------------------------------------------------------- /scripts/1.Account/3.Payer.ts: -------------------------------------------------------------------------------- 1 | import { LAMPORTS_PER_SOL } from "@solana/web3.js"; 2 | import { connection, FgGreen, FgYellow } from "../lib/vars"; 3 | import { loadOrGenerateKeypair } from "../lib/helpers"; 4 | import base58 from "bs58"; 5 | // 生成后面教程所需的支付账号Payer 6 | (async () => { 7 | // 如果存在/./.local_keys/Payer.json则读取保存的账号,否则生成新账号,并保存json文件 8 | let payer = loadOrGenerateKeypair("Payer"); 9 | console.log(`${FgGreen}publicKey 公钥/地址: ${FgYellow + payer.publicKey.toBase58()}`); 10 | console.log(`${FgGreen}secretKey 私钥: ${FgYellow}[${payer.secretKey}]`); 11 | console.log(`${FgGreen}secretKey 私钥-Base58: ${FgYellow + base58.encode(payer.secretKey)}`); 12 | // 查询余额 13 | const currentBalance = await connection.getBalance(payer.publicKey); 14 | console.log(`${FgGreen}Payer当前余额 (in lamports): ${FgYellow + currentBalance}`); 15 | console.log(`${FgGreen}Payer当前余额 (in SOL): ${FgYellow + currentBalance / LAMPORTS_PER_SOL}`); 16 | // 如果少于1sol,请求空投 17 | if (currentBalance <= LAMPORTS_PER_SOL) { 18 | console.log("请求空投..."); 19 | await connection.requestAirdrop(payer.publicKey, LAMPORTS_PER_SOL); 20 | } 21 | })(); 22 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/1.SendSimpleTx.ts: -------------------------------------------------------------------------------- 1 | import { Keypair, SystemProgram } from "@solana/web3.js"; 2 | import { connection, payer, FgGreen, FgYellow } from "../lib/vars"; 3 | import { SignTx } from "./SignTx"; 4 | import { CreateAccountIx } from "./CreateAccountIx"; 5 | import { SendVersionedTx } from "./SendVersionedTx"; 6 | import { CreateVersionedTx } from "./CreateVersionedTx"; 7 | // 创建账户Ix,签署交易,发送交易 8 | (async () => { 9 | console.log(`${FgGreen}Payer address: ${FgYellow + payer.publicKey.toBase58()}`); 10 | let to = Keypair.generate(); 11 | console.log(`${FgGreen}to address: ${FgYellow + to.publicKey.toBase58()}`); 12 | let createAccountIx = await CreateAccountIx( 13 | payer, 14 | to.publicKey, 15 | connection, 16 | SystemProgram.programId, 17 | ); 18 | const tx = await CreateVersionedTx(payer.publicKey, connection, [createAccountIx]); 19 | const signedTx = await SignTx([payer, to], tx); 20 | await SendVersionedTx(signedTx); 21 | })(); 22 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/2.SendComplexTx.ts: -------------------------------------------------------------------------------- 1 | import { Keypair, SystemProgram } from "@solana/web3.js"; 2 | import { payer, connection, STATIC_PUBLICKEY, FgGreen, FgYellow } from "../lib/vars"; 3 | import { CreateAccountIx } from "./CreateAccountIx"; 4 | import { Transfer } from "./Transfer"; 5 | import { CreateVersionedTx } from "./CreateVersionedTx"; 6 | import { SignTx } from "./SignTx"; 7 | import { SendVersionedTx } from "./SendVersionedTx"; 8 | // 创建账户Ix,两个发送交易 9 | (async () => { 10 | console.log(`${FgGreen}Payer address: ${FgYellow + payer.publicKey.toBase58()}`); 11 | let to = Keypair.generate(); 12 | console.log(`${FgGreen}to address: ${FgYellow + to.publicKey.toBase58()}`); 13 | let createAccountIx = await CreateAccountIx( 14 | payer, 15 | to.publicKey, 16 | connection, 17 | SystemProgram.programId, 18 | ); 19 | 20 | let transfer_1 = await Transfer(connection, payer, to.publicKey, 2_000); 21 | let transfer_2 = await Transfer(connection, payer, STATIC_PUBLICKEY, 1_000_000); 22 | const tx = await CreateVersionedTx(payer.publicKey, connection, [ 23 | createAccountIx, 24 | transfer_1, 25 | transfer_2, 26 | ]); 27 | const signedTx = await SignTx([payer, to], tx); 28 | 29 | await SendVersionedTx(signedTx); 30 | })(); 31 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/CreateAccountIx.ts: -------------------------------------------------------------------------------- 1 | import { Connection, Keypair, PublicKey, SystemProgram } from "@solana/web3.js"; 2 | import { getLamports } from "./MinimumBalanceForRentExemption"; 3 | // 创建账号IX 4 | export async function CreateAccountIx( 5 | payer: Keypair, 6 | Pubkey: PublicKey, 7 | connection: Connection, 8 | programId: PublicKey, 9 | space: number = 0, 10 | amount: number = 0, 11 | ) { 12 | // 请求在链上分配“空间”字节数的成本(以lamports为单位) 13 | const lamports = await getLamports(connection, space); 14 | // 使用 web3.js 辅助函数创建这个简单的指令 15 | const createAccountIx = SystemProgram.createAccount({ 16 | // `fromPubkey` - 该帐户需要签署交易 17 | fromPubkey: payer.publicKey, 18 | // `newAccountPubkey` - 在链上创建的账户地址 19 | newAccountPubkey: Pubkey, 20 | // 要存储在此帐户中的lamports 21 | lamports: lamports + amount, 22 | // 分配的总空间 23 | space: space, 24 | // 该帐户的owner程序id 25 | programId: programId, 26 | }); 27 | return createAccountIx; 28 | } 29 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/CreateVersionedTx.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PublicKey, 3 | TransactionMessage, 4 | VersionedTransaction, 5 | TransactionInstruction, 6 | Connection, 7 | } from "@solana/web3.js"; 8 | import { FgGreen, FgYellow } from "../lib/vars"; 9 | // 创建版本化交易 10 | export async function CreateVersionedTx( 11 | publicKey: PublicKey, 12 | connection: Connection, 13 | txs: TransactionInstruction[], 14 | ) { 15 | // 获取最后的区块hash 16 | let recentBlockhash = await connection.getLatestBlockhash().then(res => res.blockhash); 17 | 18 | // 创建消息 (v0) 19 | const message = new TransactionMessage({ 20 | payerKey: publicKey, 21 | recentBlockhash, 22 | instructions: txs, 23 | }).compileToV0Message(); 24 | 25 | // 用消息创建版本化交易 26 | const tx = new VersionedTransaction(message); 27 | console.log(`${FgGreen}tx.version: ${FgYellow + tx.version}`); 28 | return tx; 29 | } 30 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/MinimumBalanceForRentExemption.ts: -------------------------------------------------------------------------------- 1 | import { Connection } from "@solana/web3.js"; 2 | import { FgGreen, FgYellow } from "../lib/vars"; 3 | // 获取最小租金豁免数额 4 | export async function getLamports(connection: Connection, space: number = 0) { 5 | // 请求在链上分配“空间”字节数的成本(以lamports为单位) 6 | const lamports = await connection.getMinimumBalanceForRentExemption(space); 7 | console.log(`${FgGreen}共需要lamports: ${FgYellow + lamports}`); 8 | return lamports; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/SendVersionedTx.ts: -------------------------------------------------------------------------------- 1 | import { VersionedTransaction } from "@solana/web3.js"; 2 | import { connection, FgGreen, FgYellow, FgRed } from "../lib/vars"; 3 | import { 4 | explorerURL, 5 | extractSignatureFromFailedTransaction, 6 | printConsoleSeparator, 7 | } from "../lib/helpers"; 8 | // 发送交易 9 | export async function SendVersionedTx(tx: VersionedTransaction) { 10 | printConsoleSeparator(); 11 | try { 12 | // 实际发送交易 13 | const sig = await connection.sendTransaction(tx); 14 | // 输出浏览器链接 15 | console.log(`${FgGreen}交易完成.`); 16 | console.log(FgYellow + explorerURL({ txSignature: sig })); 17 | } catch (err) { 18 | console.error(FgRed + "发送失败:"); 19 | // 尝试从失败的交易中提取签名 20 | const failedSig = await extractSignatureFromFailedTransaction(connection, err); 21 | if (failedSig) 22 | console.log( 23 | `${FgRed}Failed signature: ${FgYellow + explorerURL({ txSignature: failedSig })}`, 24 | ); 25 | 26 | throw err; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/SignTx.ts: -------------------------------------------------------------------------------- 1 | import { Keypair, Signer, VersionedTransaction } from "@solana/web3.js"; 2 | import { FgGreen, FgYellow } from "../lib/vars"; 3 | // 签署交易 4 | export async function SignTx(signers: Signer[], tx: VersionedTransaction) { 5 | // 使用我们所需的签名者(例如'Payer'和'keypair')签署交易 6 | tx.sign(signers); 7 | console.log(`${FgGreen}签名: ${FgYellow + tx.signatures}`); 8 | return tx; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/2.VersionedTx/Transfer.ts: -------------------------------------------------------------------------------- 1 | import { Keypair, SystemProgram, PublicKey, Connection } from "@solana/web3.js"; 2 | import { getLamports } from "./MinimumBalanceForRentExemption"; 3 | import { FgGreen, FgYellow } from "../lib/vars"; 4 | // 创建发送交易 5 | export async function Transfer( 6 | connection: Connection, 7 | payer: Keypair, 8 | toPubkey: PublicKey, 9 | amount: number = 0, 10 | ) { 11 | // 请求在链上分配“空间”字节数的成本(以lamports为单位) 12 | const lamports = await getLamports(connection); 13 | // 创建一个指令用于发送交易 14 | const transferToTestWalletIx = SystemProgram.transfer({ 15 | // 要发送的数量,以lamports为单位,加上空间租用成本 16 | lamports: lamports + amount, 17 | // `fromPubkey` - 该帐户需要签署交易 18 | fromPubkey: payer.publicKey, 19 | // `toPubkey` - 不需要签署交易 20 | toPubkey: toPubkey, 21 | // 该帐户的owner程序id为系统程序id 22 | programId: SystemProgram.programId, 23 | }); 24 | return transferToTestWalletIx; 25 | } 26 | -------------------------------------------------------------------------------- /scripts/3.Token/1.CreateMint.ts: -------------------------------------------------------------------------------- 1 | import { getMint } from "@solana/spl-token"; 2 | import { connection, payer } from "../lib/vars"; 3 | import { CreateMint } from "./CreateMint"; 4 | 5 | (async () => { 6 | const mint = await CreateMint( 7 | connection, 8 | payer, 9 | payer.publicKey, 10 | payer.publicKey, 11 | 2, // 小数点精度 12 | "Token", 13 | ); 14 | 15 | // 获取铸造详情 16 | const mintInfo = await getMint(connection, mint); 17 | console.log(mintInfo); 18 | })(); 19 | -------------------------------------------------------------------------------- /scripts/3.Token/2.MintTokens.ts: -------------------------------------------------------------------------------- 1 | import { connection, payer, FgGreen, FgYellow, TokenMint } from "../lib/vars"; 2 | import { Ata } from "./ATA"; 3 | import { MintTo } from "./MintTo"; 4 | // 演示如何在现有 SPL 代币铸币厂中创建新的 SPL 代币(又名'铸造代币') 5 | (async () => { 6 | console.log(`${FgGreen}Payer address: ${FgYellow + payer.publicKey.toBase58()}`); 7 | // 读取保存的Token地址 8 | let tokenMint = TokenMint("Token"); 9 | // Ata地址 10 | const associatedTokenAccount = await Ata(connection, payer, tokenMint, payer.publicKey); 11 | // 2位精度,10000.00个 12 | const amountOfTokensToMint = 1_000_000_000_000_000; 13 | // 铸造方法 14 | await MintTo(connection, payer, tokenMint, associatedTokenAccount, payer, amountOfTokensToMint); 15 | })(); 16 | -------------------------------------------------------------------------------- /scripts/3.Token/3.Burn.ts: -------------------------------------------------------------------------------- 1 | import { connection, payer, FgGreen, FgYellow, TokenMint } from "../lib/vars"; 2 | import { Ata } from "./ATA"; 3 | import { Burn } from "./Burn"; 4 | // 演示如何在现有 SPL 代币铸币厂中创建新的 SPL 代币(又名'铸造代币') 5 | (async () => { 6 | console.log(`${FgGreen}Payer address: ${FgYellow + payer.publicKey.toBase58()}`); 7 | // 读取保存的Token地址 8 | let tokenMint = TokenMint("Token"); 9 | // Ata地址 10 | const associatedTokenAccount = await Ata(connection, payer, tokenMint, payer.publicKey); 11 | // 2位精度,10.00个 12 | const amountOfTokensToBurn = 1_000; 13 | // 销毁方法 14 | await Burn(connection, payer, associatedTokenAccount, tokenMint, payer, amountOfTokensToBurn); 15 | })(); 16 | -------------------------------------------------------------------------------- /scripts/3.Token/4.BurnAll.ts: -------------------------------------------------------------------------------- 1 | import { connection, payer, FgGreen, FgYellow, TokenMint } from "../lib/vars"; 2 | import { Ata } from "./ATA"; 3 | import { CloseAccount } from "./CloseAccount"; 4 | import { getAccount } from "@solana/spl-token"; 5 | import { Burn } from "./Burn"; 6 | // 演示如何在现有 SPL 代币铸币厂中创建新的 SPL 代币(又名'铸造代币') 7 | (async () => { 8 | console.log(`${FgGreen}Payer address: ${FgYellow + payer.publicKey.toBase58()}`); 9 | // 读取保存的Token地址 10 | let tokenMint = TokenMint("Token"); 11 | // Ata地址 12 | const associatedTokenAccount = await Ata(connection, payer, tokenMint, payer.publicKey); 13 | const balance = await getAccount(connection, associatedTokenAccount); 14 | console.log(`${FgGreen}Token Balance: ${FgYellow + balance.amount}`); 15 | // 销毁方法 16 | await Burn(connection, payer, associatedTokenAccount, tokenMint, payer, balance.amount); 17 | // 关闭账户,回收SOL 18 | await CloseAccount(connection, payer, associatedTokenAccount, payer.publicKey, payer); 19 | })(); 20 | -------------------------------------------------------------------------------- /scripts/3.Token/5.GetTokenAccountsByOwner.ts: -------------------------------------------------------------------------------- 1 | import { connection, payer, FgGreen, FgYellow } from "../lib/vars"; 2 | import { AccountLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 3 | import { PublicKey } from "@solana/web3.js"; 4 | // 查询账户下所有Token 5 | (async () => { 6 | const tokenAccounts = await connection.getTokenAccountsByOwner(payer.publicKey, { 7 | programId: TOKEN_PROGRAM_ID, 8 | }); 9 | 10 | console.log("Token Balance"); 11 | console.log("------------------------------------------------------------"); 12 | tokenAccounts.value.forEach(tokenAccount => { 13 | const accountData = AccountLayout.decode(tokenAccount.account.data); 14 | console.log(`${FgGreen + new PublicKey(accountData.mint)} ${FgYellow + accountData.amount}`); 15 | }); 16 | })(); 17 | -------------------------------------------------------------------------------- /scripts/3.Token/6.Transfer.ts: -------------------------------------------------------------------------------- 1 | import { connection, payer, FgGreen, FgYellow, TokenMint } from "../lib/vars"; 2 | import { Keypair } from "@solana/web3.js"; 3 | import { TransferToken } from "./TransferToken"; 4 | import { Ata } from "./ATA"; 5 | import { getAccount } from "@solana/spl-token"; 6 | // 发送Token 7 | (async () => { 8 | const toKeypair = Keypair.generate(); 9 | console.log(`${FgGreen}To 公钥/地址: ${FgYellow + toKeypair.publicKey.toBase58()}`); 10 | 11 | // 读取保存的Token地址 12 | let tokenMint = TokenMint("Token"); 13 | 14 | // 获取或创建From ATA 15 | const fromTokenAccount = await Ata(connection, payer, tokenMint, payer.publicKey); 16 | // 获取或创建To ATA 17 | const toTokenAccount = await Ata(connection, payer, tokenMint, toKeypair.publicKey); 18 | 19 | const fromBalanceBefore = await getAccount(connection, fromTokenAccount); 20 | const toBalanceBefore = await getAccount(connection, toTokenAccount); 21 | console.log(`${FgGreen}from Balance before: ${FgYellow + fromBalanceBefore.amount}`); 22 | console.log(`${FgGreen}to Balance before: ${FgYellow + toBalanceBefore.amount}`); 23 | 24 | // 发送Token 25 | await TransferToken(connection, payer, fromTokenAccount, toTokenAccount, payer.publicKey, 10); 26 | 27 | const fromBalanceAfter = await getAccount(connection, fromTokenAccount); 28 | const toBalanceAfter = await getAccount(connection, toTokenAccount); 29 | console.log(`${FgGreen}from Balance after: ${FgYellow + fromBalanceAfter.amount}`); 30 | console.log(`${FgGreen}to Balance after: ${FgYellow + toBalanceAfter.amount}`); 31 | })(); 32 | -------------------------------------------------------------------------------- /scripts/3.Token/7.NonFungibleToken.ts: -------------------------------------------------------------------------------- 1 | import { connection, payer } from "../lib/vars"; 2 | import { Ata } from "./ATA"; 3 | import { AuthorityType, getAccount, getMint } from "@solana/spl-token"; 4 | import { CreateMint } from "./CreateMint"; 5 | import { MintTo } from "./MintTo"; 6 | import { AddTransaction } from "../4.WrapSOL/AddTransaction"; 7 | import { SendAndConfirmTx } from "../4.WrapSOL/SendAndConfirmTx"; 8 | import { CreateSetAuthorityIx } from "./CreateSetAuthorityInstyIx"; 9 | import { FgGreen, FgYellow } from "../lib/vars"; 10 | // 创建NFT 11 | (async () => { 12 | // 创建Token,精度为0 13 | const tokenMint = await CreateMint( 14 | connection, 15 | payer, 16 | payer.publicKey, 17 | payer.publicKey, 18 | 0, // NFT的小数点精度为0 19 | "NFT", 20 | ); 21 | // 创建ATA账户 22 | const associatedTokenAccount = await Ata(connection, payer, tokenMint, payer.publicKey); 23 | // 向ATA账户铸造1个Token 24 | await MintTo(connection, payer, tokenMint, associatedTokenAccount, payer, 1); 25 | // 创建设置权限为空的指令交易 26 | let tx = AddTransaction( 27 | CreateSetAuthorityIx(tokenMint, payer.publicKey, AuthorityType.MintTokens, null), 28 | ); 29 | // 发送交易 30 | await SendAndConfirmTx(connection, tx, [payer]); 31 | // 获取账户信息 32 | const accountInfo = await getAccount(connection, associatedTokenAccount); 33 | console.log(`${FgGreen}账户余额: ${FgYellow + accountInfo.amount}`); 34 | const mintInfo = await getMint(connection, tokenMint); 35 | console.log(`${FgGreen}NFT信息:`, mintInfo); 36 | })(); 37 | -------------------------------------------------------------------------------- /scripts/3.Token/ATA.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey, Connection, Signer, Commitment, ConfirmOptions } from "@solana/web3.js"; 2 | import { 3 | ASSOCIATED_TOKEN_PROGRAM_ID, 4 | TOKEN_PROGRAM_ID, 5 | getOrCreateAssociatedTokenAccount, 6 | } from "@solana/spl-token"; 7 | import { FgGreen, FgYellow } from "../lib/vars"; 8 | 9 | /** 10 | * SPL 代币是使用一种特殊关系来拥有的, 11 | * 其中实际代币由不同的帐户存储/拥有, 12 | * 然后由用户的钱包/帐户拥有。 13 | * 这个特殊帐户称为'关联代币帐户'(或简称'ata') 14 | * 它是这样的: 15 | * Token存储在每个Token账户的ata中,然后ata由用户的钱包拥有 16 | */ 17 | // 获取或创建关联的令牌帐户 18 | export async function Ata( 19 | connection: Connection, 20 | payer: Signer, 21 | mint: PublicKey, 22 | owner: PublicKey, 23 | programId = TOKEN_PROGRAM_ID, 24 | associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID, 25 | ) { 26 | const allowOwnerOffCurve = false; 27 | const commitment: Commitment = "processed"; 28 | const confirmOptions: ConfirmOptions = {}; 29 | // 获取或者创建ATA 30 | const tokenAccount = await getOrCreateAssociatedTokenAccount( 31 | connection, 32 | payer, 33 | mint, 34 | owner, 35 | allowOwnerOffCurve, 36 | commitment, 37 | confirmOptions, 38 | programId, 39 | associatedTokenProgramId, 40 | ).then(ata => ata.address); 41 | console.log(`${FgGreen}Ata address: ${FgYellow + tokenAccount}`); 42 | return tokenAccount; 43 | } 44 | -------------------------------------------------------------------------------- /scripts/3.Token/Burn.ts: -------------------------------------------------------------------------------- 1 | import { burn } from "@solana/spl-token"; 2 | import { Connection, PublicKey, Signer } from "@solana/web3.js"; 3 | import { explorerURL } from "../lib/helpers"; 4 | import { FgGreen, FgYellow } from "../lib/vars"; 5 | 6 | export async function Burn( 7 | connection: Connection, 8 | payer: Signer, 9 | account: PublicKey, 10 | mint: PublicKey, 11 | owner: Signer | PublicKey, 12 | amount: number | bigint, 13 | ) { 14 | const mintSig = await burn( 15 | connection, // 网络链接 16 | payer, // 支付账户 17 | account, // Ata地址 18 | mint, // token地址 19 | owner, // 铸造权限 20 | amount, // 数量 21 | ); 22 | 23 | console.log(`${FgGreen}交易完成.`); 24 | console.log(FgYellow + explorerURL({ txSignature: mintSig })); 25 | } 26 | -------------------------------------------------------------------------------- /scripts/3.Token/CloseAccount.ts: -------------------------------------------------------------------------------- 1 | import { closeAccount } from "@solana/spl-token"; 2 | import { Connection, PublicKey, Signer } from "@solana/web3.js"; 3 | 4 | export async function CloseAccount( 5 | connection: Connection, 6 | payer: Signer, 7 | account: PublicKey, 8 | destination: PublicKey, 9 | authority: Signer | PublicKey, 10 | ) { 11 | await closeAccount(connection, payer, account, destination, authority); 12 | } 13 | -------------------------------------------------------------------------------- /scripts/3.Token/CreateMint.ts: -------------------------------------------------------------------------------- 1 | import { createMint, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 2 | import { savePublicKeyToFile } from "../lib/helpers"; 3 | import { Connection, Keypair, PublicKey, Signer } from "@solana/web3.js"; 4 | import { FgGreen, FgYellow } from "../lib/vars"; 5 | 6 | export async function CreateMint( 7 | connection: Connection, 8 | payer: Signer, 9 | mintAuthority: PublicKey, 10 | freezeAuthority: PublicKey | null, 11 | decimals: number, 12 | symble: string, 13 | keypair = Keypair.generate(), 14 | programId = TOKEN_PROGRAM_ID, 15 | ) { 16 | const mint = await createMint( 17 | connection, // 链接 18 | payer, // 支付账户 19 | mintAuthority, // 铸造账户地址 20 | freezeAuthority, // 冻结账户地址 21 | decimals, // 小数点精度 22 | keypair, 23 | undefined, 24 | programId, 25 | ); 26 | console.log(`${FgGreen}Mint地址: ${FgYellow + mint.toBase58()}`); 27 | // 保存Token账户地址 28 | savePublicKeyToFile(symble, mint); 29 | return mint; 30 | } 31 | -------------------------------------------------------------------------------- /scripts/3.Token/CreateSetAuthorityInstyIx.ts: -------------------------------------------------------------------------------- 1 | import { AuthorityType, createSetAuthorityInstruction } from "@solana/spl-token"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | 4 | export function CreateSetAuthorityIx( 5 | account: PublicKey, 6 | currentAuthority: PublicKey, 7 | authorityType: AuthorityType, 8 | newAuthority: PublicKey | null, 9 | ) { 10 | return createSetAuthorityInstruction(account, currentAuthority, authorityType, newAuthority); 11 | } 12 | -------------------------------------------------------------------------------- /scripts/3.Token/MintTo.ts: -------------------------------------------------------------------------------- 1 | import { mintTo } from "@solana/spl-token"; 2 | import { Connection, PublicKey, Signer } from "@solana/web3.js"; 3 | import { explorerURL } from "../lib/helpers"; 4 | import { FgGreen, FgYellow } from "../lib/vars"; 5 | 6 | export async function MintTo( 7 | connection: Connection, 8 | payer: Signer, 9 | mint: PublicKey, 10 | destination: PublicKey, 11 | authority: Signer | PublicKey, 12 | amount: number | bigint, 13 | ) { 14 | // 铸造一些数量的Token到Ata账户 15 | console.log(FgGreen + "Minting some tokens to the ata..."); 16 | const mintSig = await mintTo( 17 | connection, // 网络链接 18 | payer, // 支付账户 19 | mint, // token地址 20 | destination, // Ata地址 21 | authority, // 铸造权限 22 | amount, // 数量 23 | ); 24 | 25 | console.log(`${FgGreen}交易完成.`); 26 | console.log(FgYellow + explorerURL({ txSignature: mintSig })); 27 | } 28 | -------------------------------------------------------------------------------- /scripts/3.Token/TransferToken.ts: -------------------------------------------------------------------------------- 1 | import { transfer } from "@solana/spl-token"; 2 | import { Connection, PublicKey, Signer } from "@solana/web3.js"; 3 | import { explorerURL } from "../lib/helpers"; 4 | import { FgGreen, FgYellow } from "../lib/vars"; 5 | 6 | export async function TransferToken( 7 | connection: Connection, 8 | payer: Signer, 9 | source: PublicKey, 10 | destination: PublicKey, 11 | owner: Signer | PublicKey, 12 | amount: number | bigint, 13 | ) { 14 | const signature = await transfer(connection, payer, source, destination, owner, amount); 15 | console.log(`${FgGreen}交易完成.`); 16 | console.log(FgYellow + explorerURL({ txSignature: signature })); 17 | } 18 | -------------------------------------------------------------------------------- /scripts/4.WrapSOL/1.WrapSOL.ts: -------------------------------------------------------------------------------- 1 | import { NATIVE_MINT, getAccount } from "@solana/spl-token"; 2 | import { LAMPORTS_PER_SOL, SystemProgram } from "@solana/web3.js"; 3 | import { connection, payer, FgGreen, FgYellow } from "../lib/vars"; 4 | import { Ata } from "../3.Token/ATA"; 5 | import { AddTransaction } from "./AddTransaction"; 6 | import { SendAndConfirmTx } from "./SendAndConfirmTx"; 7 | import { CreateSyncNativeIx } from "./CreateSyncNativeIx"; 8 | // 包装SOL 9 | (async () => { 10 | // 创建Ata账户用来保存你的wrapped SOL 11 | const associatedTokenAccount = await Ata(connection, payer, NATIVE_MINT, payer.publicKey); 12 | 13 | // 将 SOL 转移到关联的代币账户并使用 SyncNative 更新wrapped SOL 余额 14 | const solTransferTransaction = AddTransaction( 15 | // 第一个交易,发送sol 16 | SystemProgram.transfer({ 17 | fromPubkey: payer.publicKey, 18 | toPubkey: associatedTokenAccount, 19 | lamports: LAMPORTS_PER_SOL, // 数量 20 | }), 21 | // 第二个交易,创建SyncNative指令 22 | CreateSyncNativeIx(associatedTokenAccount), 23 | ); 24 | // 发送和确认交易 25 | await SendAndConfirmTx(connection, solTransferTransaction, [payer]); 26 | // 获取账户信息 27 | const accountInfo = await getAccount(connection, associatedTokenAccount); 28 | 29 | console.log( 30 | `${FgGreen}Native: ${FgYellow + accountInfo.isNative}, ${FgGreen}Lamports: ${ 31 | FgYellow + accountInfo.amount 32 | }`, 33 | ); 34 | })(); 35 | -------------------------------------------------------------------------------- /scripts/4.WrapSOL/2.UnWrapSOL.ts: -------------------------------------------------------------------------------- 1 | import { NATIVE_MINT } from "@solana/spl-token"; 2 | import { connection, payer } from "../lib/vars"; 3 | import { Ata } from "../3.Token/ATA"; 4 | import { CloseAccount } from "./CloseAccount"; 5 | // 包装SOL 6 | (async () => { 7 | // 创建Ata账户用来保存你的wrapped SOL 8 | const associatedTokenAccount = await Ata(connection, payer, NATIVE_MINT, payer.publicKey); 9 | // 关闭账户,回收SOL 10 | await CloseAccount(connection, payer, associatedTokenAccount, payer.publicKey, payer); 11 | })(); 12 | -------------------------------------------------------------------------------- /scripts/4.WrapSOL/AddTransaction.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Transaction, 3 | TransactionInstruction, 4 | TransactionInstructionCtorFields, 5 | } from "@solana/web3.js"; 6 | 7 | export function AddTransaction( 8 | ...items: (Transaction | TransactionInstruction | TransactionInstructionCtorFields)[] 9 | ) { 10 | return new Transaction().add(...items); 11 | } 12 | -------------------------------------------------------------------------------- /scripts/4.WrapSOL/CloseAccount.ts: -------------------------------------------------------------------------------- 1 | import { closeAccount } from "@solana/spl-token"; 2 | import { Connection, PublicKey, Signer } from "@solana/web3.js"; 3 | import { FgGreen, FgYellow } from "../lib/vars"; 4 | 5 | export async function CloseAccount( 6 | connection: Connection, 7 | payer: Signer, 8 | account: PublicKey, 9 | destination: PublicKey, 10 | authority: Signer | PublicKey, 11 | ) { 12 | const walletBalance = await connection.getBalance(payer.publicKey); 13 | console.log(`${FgGreen}Balance before unwrapping 1 WSOL: ${FgYellow + walletBalance}`); 14 | 15 | await closeAccount(connection, payer, account, destination, authority); 16 | 17 | const walletBalancePostClose = await connection.getBalance(payer.publicKey); 18 | console.log(`${FgGreen}Balance after unwrapping 1 WSOL: ${FgYellow + walletBalancePostClose}`); 19 | } 20 | -------------------------------------------------------------------------------- /scripts/4.WrapSOL/CreateSyncNativeIx.ts: -------------------------------------------------------------------------------- 1 | import { TOKEN_PROGRAM_ID, createSyncNativeInstruction } from "@solana/spl-token"; 2 | import { PublicKey } from "@solana/web3.js"; 3 | 4 | export function CreateSyncNativeIx(account: PublicKey, programId = TOKEN_PROGRAM_ID) { 5 | return createSyncNativeInstruction(account, programId); 6 | } 7 | -------------------------------------------------------------------------------- /scripts/4.WrapSOL/SendAndConfirmTx.ts: -------------------------------------------------------------------------------- 1 | import { Connection, Signer, Transaction, sendAndConfirmTransaction } from "@solana/web3.js"; 2 | import { FgGreen, FgYellow, FgRed } from "../lib/vars"; 3 | import { 4 | explorerURL, 5 | extractSignatureFromFailedTransaction, 6 | printConsoleSeparator, 7 | } from "../lib/helpers"; 8 | export async function SendAndConfirmTx( 9 | connection: Connection, 10 | transaction: Transaction, 11 | signers: Signer[], 12 | ) { 13 | printConsoleSeparator(); 14 | try { 15 | // 实际发送交易 16 | const sig = await sendAndConfirmTransaction(connection, transaction, signers); 17 | // 输出浏览器链接 18 | console.log(`${FgGreen}交易完成.`); 19 | console.log(FgYellow + explorerURL({ txSignature: sig })); 20 | } catch (err) { 21 | console.error(FgRed + "发送失败:"); 22 | // 尝试从失败的交易中提取签名 23 | const failedSig = await extractSignatureFromFailedTransaction(connection, err); 24 | if (failedSig) 25 | console.log( 26 | `${FgRed}Failed signature: ${FgYellow + explorerURL({ txSignature: failedSig })}`, 27 | ); 28 | 29 | throw err; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/1.TokenStandards/TokenStandard.ts: -------------------------------------------------------------------------------- 1 | // https://developers.metaplex.com/token-metadata/token-standard#the-token-standard-field 2 | export const Fungible = { 3 | name: "USD Coin", 4 | symbol: "USDC", 5 | description: "Fully reserved fiat-backed stablecoin created by Circle.", 6 | image: "https://www.circle.com/hs-fs/hubfs/sundaes/USDC.png?width=540&height=540&name=USDC.png", 7 | }; 8 | 9 | export const FungibleAsset = { 10 | name: "SolanaGame Steel Sword", 11 | symbol: "SG-SS-1", 12 | description: "SolanaGame steel sword available after Level 4", 13 | image: "", 14 | animation_url: "", 15 | external_url: "", 16 | attributes: [ 17 | { 18 | trait_type: "attack", 19 | value: "4", 20 | }, 21 | { 22 | trait_type: "defense", 23 | value: "3", 24 | }, 25 | { 26 | trait_type: "durability", 27 | value: "47", 28 | }, 29 | { 30 | trait_type: "components", 31 | value: "iron: 10; carbon: 1; wood: 2", 32 | }, 33 | ], 34 | }; 35 | 36 | export const NonFungible = { 37 | name: "SolanaArtProject #1", 38 | description: "Generative art on Solana.", 39 | image: "https://arweave.net/ysO06edn023KqdO5QGe4ZECZGry1DO19vTgL86AF2Zc", 40 | animation_url: "https://arweave.net/aMZ8N-TiQkRkyMzAn3UOWCqMyvz42sjIeLUv4i3Aq2s", 41 | external_url: "https://example.com", 42 | symbol: "S-NFT", 43 | attributes: [ 44 | { 45 | trait_type: "trait1", 46 | value: "value1", 47 | }, 48 | { 49 | trait_type: "trait2", 50 | value: "value2", 51 | }, 52 | ], 53 | properties: { 54 | files: [ 55 | { 56 | uri: "https://www.arweave.net/abcd5678?ext=png", 57 | type: "image/png", 58 | }, 59 | { 60 | uri: "https://watch.videodelivery.net/9876jkl", 61 | type: "unknown", 62 | cdn: true, 63 | }, 64 | { 65 | uri: "https://www.arweave.net/efgh1234?ext=mp4", 66 | type: "video/mp4", 67 | }, 68 | ], 69 | category: "video", 70 | 71 | // @deprecated 72 | // Do not use - may be removed in a future release. 73 | // Use on-chain data instead. 74 | collection: { 75 | name: "Solflare X NFT", 76 | family: "Solflare", 77 | }, 78 | 79 | // @deprecated 80 | // Do not use - may be removed in a future release. 81 | // Use on-chain data instead. 82 | creators: [ 83 | { 84 | address: "xEtQ9Fpv62qdc1GYfpNReMasVTe9YW5bHJwfVKqo72u", 85 | share: 100, 86 | }, 87 | ], 88 | }, 89 | }; 90 | 91 | export const ProgramableNonFungible = { 92 | name: "SolanaArtProject #1", 93 | description: "Generative art on Solana.", 94 | image: "https://arweave.net/26YdhY_eAzv26YdhY1uu9uiA3nmDZYwP8MwZAultcE?ext=jpeg", 95 | animation_url: "https://arweave.net/ZAultcE_eAzv26YdhY1uu9uiA3nmDZYwP8MwuiA3nm?ext=glb", 96 | external_url: "https://example.com", 97 | attributes: [ 98 | { 99 | trait_type: "trait1", 100 | value: "value1", 101 | }, 102 | { 103 | trait_type: "trait2", 104 | value: "value2", 105 | }, 106 | ], 107 | properties: { 108 | files: [ 109 | { 110 | uri: "https://www.arweave.net/abcd5678?ext=png", 111 | type: "image/png", 112 | }, 113 | { 114 | uri: "https://watch.videodelivery.net/9876jkl", 115 | type: "unknown", 116 | cdn: true, 117 | }, 118 | { 119 | uri: "https://www.arweave.net/efgh1234?ext=mp4", 120 | type: "video/mp4", 121 | }, 122 | ], 123 | category: "video", 124 | }, 125 | }; 126 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/1.AuthorityItemDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateAuthorityItemV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection_NFT")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateAuthorityItemV1(umi, { 24 | mint, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.NonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/1.AuthorityItemDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeAuthorityItemV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection_NFT")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeAuthorityItemV1(umi, { 23 | mint, 24 | authority: signer, 25 | delegate: publicKey(delegate.publicKey), 26 | tokenStandard: TokenStandard.NonFungible, 27 | }) 28 | .sendAndConfirm(umi) 29 | .then(({ signature }) => { 30 | txExplorer(signature); 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/1.AuthorityItemDelegate/3.Update.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | mplTokenMetadata, 7 | updateAsAuthorityItemDelegateV2, 8 | } from "@metaplex-foundation/mpl-token-metadata"; 9 | 10 | (async () => { 11 | const umi = createUmi(CLUSTER_URL); 12 | const signer = createSignerFromKeypair(umi, umiPayer); 13 | umi.use(signerIdentity(signer, true)); 14 | umi.use(mplTokenMetadata()); 15 | 16 | // 读取保存的Delegate 17 | let delegateKeyPair = UmiKeypair("Delegate"); 18 | console.log("Delegate address:", delegateKeyPair.publicKey); 19 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 20 | 21 | // 读取保存的Token地址 22 | let mint = publicKey(TokenMint("umi_collection_NFT")); 23 | 24 | await updateAsAuthorityItemDelegateV2(umi, { 25 | mint, 26 | payer: signer, 27 | authority: delegate, 28 | isMutable: false, 29 | }) 30 | .sendAndConfirm(umi) 31 | .then(({ signature }) => { 32 | txExplorer(signature); 33 | }); 34 | })(); 35 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/10.TransferDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateTransferV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateTransferV1(umi, { 24 | mint: mint, 25 | tokenOwner: signer.publicKey, 26 | authority: signer, 27 | delegate: publicKey(delegate.publicKey), 28 | tokenStandard: TokenStandard.ProgrammableNonFungible, 29 | }) 30 | .sendAndConfirm(umi) 31 | .then(({ signature }) => { 32 | txExplorer(signature); 33 | }); 34 | })(); 35 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/10.TransferDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeTransferV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeTransferV1(umi, { 23 | mint, 24 | tokenOwner: signer.publicKey, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/10.TransferDelegate/3.Transfer.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 10 | import { 11 | TokenStandard, 12 | mplTokenMetadata, 13 | transferV1, 14 | } from "@metaplex-foundation/mpl-token-metadata"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | umi.use(mplTokenMetadata()); 21 | 22 | // 读取保存的Delegate 23 | let delegateKeyPair = UmiKeypair("Delegate"); 24 | console.log("Delegate address:", delegateKeyPair.publicKey); 25 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 26 | 27 | // 读取保存的Token地址 28 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 29 | let receiver = generateSigner(umi); 30 | 31 | await transferV1(umi, { 32 | mint, 33 | authority: delegate, 34 | payer: signer, 35 | tokenOwner: signer.publicKey, 36 | destinationOwner: receiver.publicKey, 37 | tokenStandard: TokenStandard.ProgrammableNonFungible, 38 | }) 39 | .sendAndConfirm(umi) 40 | .then(({ signature }) => { 41 | txExplorer(signature); 42 | }); 43 | })(); 44 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/11.LockedTransferDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 10 | import { umiPayer } from "../../../lib/umiHelper"; 11 | import { 12 | TokenStandard, 13 | delegateLockedTransferV1, 14 | mplTokenMetadata, 15 | } from "@metaplex-foundation/mpl-token-metadata"; 16 | 17 | (async () => { 18 | const umi = createUmi(CLUSTER_URL); 19 | const signer = createSignerFromKeypair(umi, umiPayer); 20 | umi.use(signerIdentity(signer, true)); 21 | umi.use(mplTokenMetadata()); 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 24 | // 计算Delegate 25 | let delegate = loadOrGenerateKeypair("Delegate"); 26 | console.log("Delegate address:", delegate.publicKey.toBase58()); 27 | 28 | await delegateLockedTransferV1(umi, { 29 | mint: mint, 30 | tokenOwner: signer.publicKey, 31 | authority: signer, 32 | delegate: publicKey(delegate.publicKey), 33 | tokenStandard: TokenStandard.ProgrammableNonFungible, 34 | lockedAddress: generateSigner(umi).publicKey, 35 | }) 36 | .sendAndConfirm(umi) 37 | .then(({ signature }) => { 38 | txExplorer(signature); 39 | }); 40 | })(); 41 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/11.LockedTransferDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeLockedTransferV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeLockedTransferV1(umi, { 23 | mint, 24 | tokenOwner: signer.publicKey, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/11.LockedTransferDelegate/3.Transfer.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 10 | import { 11 | TokenStandard, 12 | mplTokenMetadata, 13 | transferV1, 14 | } from "@metaplex-foundation/mpl-token-metadata"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | umi.use(mplTokenMetadata()); 21 | 22 | // 读取保存的Delegate 23 | let delegateKeyPair = UmiKeypair("Delegate"); 24 | console.log("Delegate address:", delegateKeyPair.publicKey); 25 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 26 | 27 | // 读取保存的Token地址 28 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 29 | let receiver = generateSigner(umi); 30 | 31 | await transferV1(umi, { 32 | mint, 33 | authority: delegate, 34 | payer: signer, 35 | tokenOwner: signer.publicKey, 36 | destinationOwner: receiver.publicKey, 37 | tokenStandard: TokenStandard.ProgrammableNonFungible, 38 | }) 39 | .sendAndConfirm(umi) 40 | .then(({ signature }) => { 41 | txExplorer(signature); 42 | }); 43 | })(); 44 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/11.LockedTransferDelegate/4.Lock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | publicKey, 6 | signerIdentity, 7 | } from "@metaplex-foundation/umi"; 8 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 9 | import { TokenStandard, lockV1, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 24 | await lockV1(umi, { 25 | mint, 26 | authority: delegate, 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/11.LockedTransferDelegate/5.Unlock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { TokenStandard, mplTokenMetadata, unlockV1 } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | umi.use(mplTokenMetadata()); 12 | 13 | // 读取保存的Delegate 14 | let delegateKeyPair = UmiKeypair("Delegate"); 15 | console.log("Delegate address:", delegateKeyPair.publicKey); 16 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 17 | 18 | // 读取保存的Token地址 19 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 20 | 21 | await unlockV1(umi, { 22 | mint, 23 | authority: delegate, 24 | tokenStandard: TokenStandard.ProgrammableNonFungible, 25 | }) 26 | .sendAndConfirm(umi) 27 | .then(({ signature }) => { 28 | txExplorer(signature); 29 | }); 30 | })(); 31 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/12.UtilityDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | publicKey, 6 | signerIdentity, 7 | } from "@metaplex-foundation/umi"; 8 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 9 | import { umiPayer } from "../../../lib/umiHelper"; 10 | import { 11 | TokenStandard, 12 | delegateUtilityV1, 13 | mplTokenMetadata, 14 | } from "@metaplex-foundation/mpl-token-metadata"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | umi.use(mplTokenMetadata()); 21 | // 读取保存的Token地址 22 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 23 | // 计算Delegate 24 | let delegate = loadOrGenerateKeypair("Delegate"); 25 | console.log("Delegate address:", delegate.publicKey.toBase58()); 26 | 27 | await delegateUtilityV1(umi, { 28 | mint: mint, 29 | tokenOwner: signer.publicKey, 30 | authority: signer, 31 | delegate: publicKey(delegate.publicKey), 32 | tokenStandard: TokenStandard.ProgrammableNonFungible, 33 | }) 34 | .sendAndConfirm(umi) 35 | .then(({ signature }) => { 36 | txExplorer(signature); 37 | }); 38 | })(); 39 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/12.UtilityDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeUtilityV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeUtilityV1(umi, { 23 | mint, 24 | tokenOwner: signer.publicKey, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/12.UtilityDelegate/3.Burn.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { TokenStandard, burnV1, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | umi.use(mplTokenMetadata()); 12 | 13 | // 读取保存的Delegate 14 | let delegateKeyPair = UmiKeypair("Delegate"); 15 | console.log("Delegate address:", delegateKeyPair.publicKey); 16 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 17 | 18 | // 读取保存的Token地址 19 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 20 | 21 | await burnV1(umi, { 22 | mint, 23 | authority: delegate, 24 | tokenOwner: signer.publicKey, 25 | tokenStandard: TokenStandard.ProgrammableNonFungible, 26 | }) 27 | .sendAndConfirm(umi) 28 | .then(({ signature }) => { 29 | txExplorer(signature); 30 | }); 31 | })(); 32 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/12.UtilityDelegate/4.Lock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | publicKey, 6 | signerIdentity, 7 | } from "@metaplex-foundation/umi"; 8 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 9 | import { TokenStandard, lockV1, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 24 | await lockV1(umi, { 25 | mint, 26 | authority: delegate, 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/12.UtilityDelegate/5.Unlock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { TokenStandard, mplTokenMetadata, unlockV1 } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | umi.use(mplTokenMetadata()); 12 | 13 | // 读取保存的Delegate 14 | let delegateKeyPair = UmiKeypair("Delegate"); 15 | console.log("Delegate address:", delegateKeyPair.publicKey); 16 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 17 | 18 | // 读取保存的Token地址 19 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 20 | 21 | await unlockV1(umi, { 22 | mint, 23 | authority: delegate, 24 | tokenStandard: TokenStandard.ProgrammableNonFungible, 25 | }) 26 | .sendAndConfirm(umi) 27 | .then(({ signature }) => { 28 | txExplorer(signature); 29 | }); 30 | })(); 31 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/13.StakingDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | publicKey, 6 | signerIdentity, 7 | } from "@metaplex-foundation/umi"; 8 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 9 | import { umiPayer } from "../../../lib/umiHelper"; 10 | import { 11 | TokenStandard, 12 | delegateStakingV1, 13 | mplTokenMetadata, 14 | } from "@metaplex-foundation/mpl-token-metadata"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | umi.use(mplTokenMetadata()); 21 | // 读取保存的Token地址 22 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 23 | // 计算Delegate 24 | let delegate = loadOrGenerateKeypair("Delegate"); 25 | console.log("Delegate address:", delegate.publicKey.toBase58()); 26 | 27 | await delegateStakingV1(umi, { 28 | mint: mint, 29 | tokenOwner: signer.publicKey, 30 | authority: signer, 31 | delegate: publicKey(delegate.publicKey), 32 | tokenStandard: TokenStandard.ProgrammableNonFungible, 33 | }) 34 | .sendAndConfirm(umi) 35 | .then(({ signature }) => { 36 | txExplorer(signature); 37 | }); 38 | })(); 39 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/13.StakingDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeStakingV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeStakingV1(umi, { 23 | mint, 24 | tokenOwner: signer.publicKey, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/13.StakingDelegate/3.Lock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | publicKey, 6 | signerIdentity, 7 | } from "@metaplex-foundation/umi"; 8 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 9 | import { TokenStandard, lockV1, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 24 | await lockV1(umi, { 25 | mint, 26 | authority: delegate, 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/13.StakingDelegate/4.Unlock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { TokenStandard, mplTokenMetadata, unlockV1 } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | umi.use(mplTokenMetadata()); 12 | 13 | // 读取保存的Delegate 14 | let delegateKeyPair = UmiKeypair("Delegate"); 15 | console.log("Delegate address:", delegateKeyPair.publicKey); 16 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 17 | 18 | // 读取保存的Token地址 19 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 20 | 21 | await unlockV1(umi, { 22 | mint, 23 | authority: delegate, 24 | tokenStandard: TokenStandard.ProgrammableNonFungible, 25 | }) 26 | .sendAndConfirm(umi) 27 | .then(({ signature }) => { 28 | txExplorer(signature); 29 | }); 30 | })(); 31 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/2.CollectionDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateCollectionV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateCollectionV1(umi, { 24 | mint: mint, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.NonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/2.CollectionDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeCollectionV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeCollectionV1(umi, { 23 | mint, 24 | authority: signer, 25 | delegate: publicKey(delegate.publicKey), 26 | tokenStandard: TokenStandard.NonFungible, 27 | }) 28 | .sendAndConfirm(umi) 29 | .then(({ signature }) => { 30 | txExplorer(signature); 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/2.CollectionDelegate/3.Update.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | collectionToggle, 7 | mplTokenMetadata, 8 | updateAsCollectionDelegateV2, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_collection")); 24 | 25 | await updateAsCollectionDelegateV2(umi, { 26 | mint, 27 | payer: signer, 28 | authority: delegate, 29 | collection: collectionToggle("Set", [{ key: mint, verified: false }]), 30 | }) 31 | .sendAndConfirm(umi) 32 | .then(({ signature }) => { 33 | txExplorer(signature); 34 | }); 35 | 36 | await updateAsCollectionDelegateV2(umi, { 37 | mint, 38 | delegateMint: mint, 39 | authority: delegate, 40 | collection: collectionToggle("Clear"), 41 | }) 42 | .sendAndConfirm(umi) 43 | .then(({ signature }) => { 44 | txExplorer(signature); 45 | }); 46 | })(); 47 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/3.CollectionItemDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateCollectionItemV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection_NFT")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateCollectionItemV1(umi, { 24 | mint: mint, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.NonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/3.CollectionItemDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeCollectionItemV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection_NFT")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeCollectionItemV1(umi, { 23 | mint, 24 | authority: signer, 25 | delegate: publicKey(delegate.publicKey), 26 | tokenStandard: TokenStandard.NonFungible, 27 | }) 28 | .sendAndConfirm(umi) 29 | .then(({ signature }) => { 30 | txExplorer(signature); 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/3.CollectionItemDelegate/3.Update.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | collectionToggle, 7 | mplTokenMetadata, 8 | updateAsCollectionItemDelegateV2, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_collection_NFT")); 24 | 25 | await updateAsCollectionItemDelegateV2(umi, { 26 | mint, 27 | payer: signer, 28 | authority: delegate, 29 | collection: collectionToggle("Set", [{ key: mint, verified: false }]), 30 | }) 31 | .sendAndConfirm(umi) 32 | .then(({ signature }) => { 33 | txExplorer(signature); 34 | }); 35 | })(); 36 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/4.DataDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateDataV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateDataV1(umi, { 24 | mint: mint, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.NonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/4.DataDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeDataV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeDataV1(umi, { 23 | mint, 24 | authority: signer, 25 | delegate: publicKey(delegate.publicKey), 26 | tokenStandard: TokenStandard.NonFungible, 27 | }) 28 | .sendAndConfirm(umi) 29 | .then(({ signature }) => { 30 | txExplorer(signature); 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/4.DataDelegate/3.Update.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | fetchMetadataFromSeeds, 7 | mplTokenMetadata, 8 | updateAsDataDelegateV2, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 24 | const initialMetadata = await fetchMetadataFromSeeds(umi, { mint }); 25 | 26 | await updateAsDataDelegateV2(umi, { 27 | mint, 28 | payer: signer, 29 | authority: delegate, 30 | data: { ...initialMetadata, name: "Updated Name" }, 31 | }) 32 | .sendAndConfirm(umi) 33 | .then(({ signature }) => { 34 | txExplorer(signature); 35 | }); 36 | })(); 37 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/5.DataItemDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateDataItemV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection_NFT")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateDataItemV1(umi, { 24 | mint: mint, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.NonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/5.DataItemDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeDataItemV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_collection_NFT")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeDataItemV1(umi, { 23 | mint, 24 | authority: signer, 25 | delegate: publicKey(delegate.publicKey), 26 | tokenStandard: TokenStandard.NonFungible, 27 | }) 28 | .sendAndConfirm(umi) 29 | .then(({ signature }) => { 30 | txExplorer(signature); 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/5.DataItemDelegate/3.Update.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | fetchMetadataFromSeeds, 7 | mplTokenMetadata, 8 | updateAsDataItemDelegateV2, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_collection_NFT")); 24 | const initialMetadata = await fetchMetadataFromSeeds(umi, { mint }); 25 | 26 | await updateAsDataItemDelegateV2(umi, { 27 | mint, 28 | payer: signer, 29 | authority: delegate, 30 | data: { ...initialMetadata, name: "Updated Name" }, 31 | }) 32 | .sendAndConfirm(umi) 33 | .then(({ signature }) => { 34 | txExplorer(signature); 35 | }); 36 | })(); 37 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/6.ProgrammableConfigDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateProgrammableConfigV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateProgrammableConfigV1(umi, { 24 | mint: mint, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/6.ProgrammableConfigDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeProgrammableConfigV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeProgrammableConfigV1(umi, { 23 | mint, 24 | authority: signer, 25 | delegate: publicKey(delegate.publicKey), 26 | tokenStandard: TokenStandard.NonFungible, 27 | }) 28 | .sendAndConfirm(umi) 29 | .then(({ signature }) => { 30 | txExplorer(signature); 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/6.ProgrammableConfigDelegate/3.Update.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { findAssociatedTokenPda } from "@metaplex-foundation/mpl-toolbox"; 10 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 11 | import { 12 | mplTokenMetadata, 13 | ruleSetToggle, 14 | updateAsProgrammableConfigDelegateV2, 15 | } from "@metaplex-foundation/mpl-token-metadata"; 16 | 17 | (async () => { 18 | const umi = createUmi(CLUSTER_URL); 19 | const signer = createSignerFromKeypair(umi, umiPayer); 20 | umi.use(signerIdentity(signer, true)); 21 | umi.use(mplTokenMetadata()); 22 | 23 | // 读取保存的Delegate 24 | let delegateKeyPair = UmiKeypair("Delegate"); 25 | console.log("Delegate address:", delegateKeyPair.publicKey); 26 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 27 | 28 | // 读取保存的Token地址 29 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 30 | const ruleSet = generateSigner(umi); 31 | 32 | await updateAsProgrammableConfigDelegateV2(umi, { 33 | mint, 34 | payer: signer, 35 | token: findAssociatedTokenPda(umi, { mint, owner: signer.publicKey }), 36 | authority: delegate, 37 | ruleSet: ruleSetToggle("Set", [ruleSet.publicKey]), 38 | }) 39 | .sendAndConfirm(umi) 40 | .then(({ signature }) => { 41 | txExplorer(signature); 42 | }); 43 | })(); 44 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/7.ProgrammableConfigItemDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateProgrammableConfigItemV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateProgrammableConfigItemV1(umi, { 24 | mint: mint, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/7.ProgrammableConfigItemDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeProgrammableConfigItemV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeProgrammableConfigItemV1(umi, { 23 | mint, 24 | authority: signer, 25 | delegate: publicKey(delegate.publicKey), 26 | tokenStandard: TokenStandard.ProgrammableNonFungible, 27 | }) 28 | .sendAndConfirm(umi) 29 | .then(({ signature }) => { 30 | txExplorer(signature); 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/7.ProgrammableConfigItemDelegate/3.Update.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { findAssociatedTokenPda } from "@metaplex-foundation/mpl-toolbox"; 10 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 11 | import { 12 | mplTokenMetadata, 13 | ruleSetToggle, 14 | updateAsProgrammableConfigItemDelegateV2, 15 | } from "@metaplex-foundation/mpl-token-metadata"; 16 | 17 | (async () => { 18 | const umi = createUmi(CLUSTER_URL); 19 | const signer = createSignerFromKeypair(umi, umiPayer); 20 | umi.use(signerIdentity(signer, true)); 21 | umi.use(mplTokenMetadata()); 22 | 23 | // 读取保存的Delegate 24 | let delegateKeyPair = UmiKeypair("Delegate"); 25 | console.log("Delegate address:", delegateKeyPair.publicKey); 26 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 27 | 28 | // 读取保存的Token地址 29 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 30 | const ruleSet = generateSigner(umi); 31 | 32 | await updateAsProgrammableConfigItemDelegateV2(umi, { 33 | mint, 34 | payer: signer, 35 | token: findAssociatedTokenPda(umi, { mint, owner: signer.publicKey }), 36 | authority: delegate, 37 | ruleSet: ruleSetToggle("Set", [ruleSet.publicKey]), 38 | }) 39 | .sendAndConfirm(umi) 40 | .then(({ signature }) => { 41 | txExplorer(signature); 42 | }); 43 | })(); 44 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/8.StandardDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateStandardV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateStandardV1(umi, { 24 | mint: mint, 25 | tokenOwner: signer.publicKey, 26 | authority: signer, 27 | delegate: publicKey(delegate.publicKey), 28 | tokenStandard: TokenStandard.NonFungible, 29 | }) 30 | .sendAndConfirm(umi) 31 | .then(({ signature }) => { 32 | txExplorer(signature); 33 | }); 34 | })(); 35 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/8.StandardDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeStandardV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeStandardV1(umi, { 23 | mint, 24 | tokenOwner: signer.publicKey, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.NonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/8.StandardDelegate/3.Transfer.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 10 | import { 11 | TokenStandard, 12 | mplTokenMetadata, 13 | transferV1, 14 | } from "@metaplex-foundation/mpl-token-metadata"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | umi.use(mplTokenMetadata()); 21 | 22 | // 读取保存的Delegate 23 | let delegateKeyPair = UmiKeypair("Delegate"); 24 | console.log("Delegate address:", delegateKeyPair.publicKey); 25 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 26 | 27 | // 读取保存的Token地址 28 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 29 | let receiver = generateSigner(umi); 30 | 31 | await transferV1(umi, { 32 | mint, 33 | authority: delegate, 34 | payer: signer, 35 | tokenOwner: signer.publicKey, 36 | destinationOwner: receiver.publicKey, 37 | tokenStandard: TokenStandard.NonFungible, 38 | }) 39 | .sendAndConfirm(umi) 40 | .then(({ signature }) => { 41 | txExplorer(signature); 42 | }); 43 | })(); 44 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/8.StandardDelegate/4.Burn.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | publicKey, 6 | signerIdentity, 7 | } from "@metaplex-foundation/umi"; 8 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 9 | import { 10 | TokenStandard, 11 | burnV1, 12 | mplTokenMetadata, 13 | } from "@metaplex-foundation/mpl-token-metadata"; 14 | 15 | (async () => { 16 | const umi = createUmi(CLUSTER_URL); 17 | const signer = createSignerFromKeypair(umi, umiPayer); 18 | umi.use(signerIdentity(signer, true)); 19 | umi.use(mplTokenMetadata()); 20 | 21 | // 读取保存的Delegate 22 | let delegateKeyPair = UmiKeypair("Delegate"); 23 | console.log("Delegate address:", delegateKeyPair.publicKey); 24 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 25 | 26 | // 读取保存的Token地址 27 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 28 | 29 | await burnV1(umi, { 30 | mint, 31 | authority: delegate, 32 | tokenOwner: signer.publicKey, 33 | tokenStandard: TokenStandard.NonFungible, 34 | }) 35 | .sendAndConfirm(umi) 36 | .then(({ signature }) => { 37 | txExplorer(signature); 38 | }); 39 | })(); 40 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/8.StandardDelegate/5.Lock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | publicKey, 6 | signerIdentity, 7 | } from "@metaplex-foundation/umi"; 8 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 9 | import { TokenStandard, lockV1, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Delegate 18 | let delegateKeyPair = UmiKeypair("Delegate"); 19 | console.log("Delegate address:", delegateKeyPair.publicKey); 20 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 21 | 22 | // 读取保存的Token地址 23 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 24 | await lockV1(umi, { 25 | mint, 26 | authority: delegate, 27 | tokenStandard: TokenStandard.NonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/8.StandardDelegate/6.Unlock.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 5 | import { TokenStandard, mplTokenMetadata, unlockV1 } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | umi.use(mplTokenMetadata()); 12 | 13 | // 读取保存的Delegate 14 | let delegateKeyPair = UmiKeypair("Delegate"); 15 | console.log("Delegate address:", delegateKeyPair.publicKey); 16 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 17 | 18 | // 读取保存的Token地址 19 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 20 | 21 | await unlockV1(umi, { 22 | mint, 23 | authority: delegate, 24 | tokenStandard: TokenStandard.NonFungible, 25 | }) 26 | .sendAndConfirm(umi) 27 | .then(({ signature }) => { 28 | txExplorer(signature); 29 | }); 30 | })(); 31 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/9.SaleDelegate/1.Approve.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 5 | import { umiPayer } from "../../../lib/umiHelper"; 6 | import { 7 | TokenStandard, 8 | delegateSaleV1, 9 | mplTokenMetadata, 10 | } from "@metaplex-foundation/mpl-token-metadata"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 计算Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | console.log("Delegate address:", delegate.publicKey.toBase58()); 22 | 23 | await delegateSaleV1(umi, { 24 | mint: mint, 25 | tokenOwner: signer.publicKey, 26 | authority: signer, 27 | delegate: publicKey(delegate.publicKey), 28 | tokenStandard: TokenStandard.ProgrammableNonFungible, 29 | }) 30 | .sendAndConfirm(umi) 31 | .then(({ signature }) => { 32 | txExplorer(signature); 33 | }); 34 | })(); 35 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/9.SaleDelegate/2.Revoke.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | revokeSaleV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { loadOrGenerateKeypair } from "../../../lib/helpers"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_ProgramableNonFungibl_token")); 19 | // 读取保存的Delegate 20 | let delegate = loadOrGenerateKeypair("Delegate"); 21 | 22 | await revokeSaleV1(umi, { 23 | mint, 24 | tokenOwner: signer.publicKey, 25 | authority: signer, 26 | delegate: publicKey(delegate.publicKey), 27 | tokenStandard: TokenStandard.ProgrammableNonFungible, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/10.DelegatedAuthorities/9.SaleDelegate/3.Transfer.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { UmiKeypair, umiPayer } from "../../../lib/umiHelper"; 10 | import { 11 | TokenStandard, 12 | mplTokenMetadata, 13 | transferV1, 14 | } from "@metaplex-foundation/mpl-token-metadata"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | umi.use(mplTokenMetadata()); 21 | 22 | // 读取保存的Delegate 23 | let delegateKeyPair = UmiKeypair("Delegate"); 24 | console.log("Delegate address:", delegateKeyPair.publicKey); 25 | const delegate = createSignerFromKeypair(umi, delegateKeyPair); 26 | 27 | // 读取保存的Token地址 28 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 29 | let receiver = generateSigner(umi); 30 | 31 | await transferV1(umi, { 32 | mint, 33 | authority: delegate, 34 | payer: signer, 35 | tokenOwner: signer.publicKey, 36 | destinationOwner: receiver.publicKey, 37 | tokenStandard: TokenStandard.ProgrammableNonFungible, 38 | }) 39 | .sendAndConfirm(umi) 40 | .then(({ signature }) => { 41 | txExplorer(signature); 42 | }); 43 | })(); 44 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/2.MintingAssets/1.UploadMetadata.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, FgGreen, FgYellow } from "../../lib/vars"; 3 | import { irysUploader } from "@metaplex-foundation/umi-uploader-irys"; 4 | import { 5 | createGenericFile, 6 | createSignerFromKeypair, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { umiPayer } from "../../lib/umiHelper"; 10 | import path from "path"; 11 | import fs from "fs"; 12 | import { Fungible } from "../1.TokenStandards/TokenStandard"; 13 | import { LAMPORTS_PER_SOL } from "@solana/web3.js"; 14 | 15 | // 上传metadata数据 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | umi.use(irysUploader()); 19 | const signer = createSignerFromKeypair(umi, umiPayer); 20 | umi.use(signerIdentity(signer, true)); 21 | 22 | const fileBuffer = fs.readFileSync(path.join("img", "Whaler_logo.gif")); 23 | const file = createGenericFile(fileBuffer, "Whaler_logo.gif", { 24 | contentType: "image/gif", 25 | }); 26 | 27 | const uploadPrice = await umi.uploader.getUploadPrice([file]); 28 | const [imageUri] = await umi.uploader.upload([file]); 29 | const uri = await umi.uploader.uploadJson({ 30 | name: Fungible.name, 31 | symbol: Fungible.symbol, 32 | description: Fungible.description, 33 | image: imageUri, 34 | }); 35 | 36 | console.log(`${FgGreen}payer => ${FgYellow + signer.publicKey.toString()}`); 37 | console.log( 38 | `${FgGreen}uploadPrice => ${FgYellow} ${ 39 | FgYellow + Number(uploadPrice.basisPoints) / LAMPORTS_PER_SOL 40 | } ${FgGreen + uploadPrice.identifier}`, 41 | ); 42 | console.log(`${FgGreen}uri => ${FgYellow + uri}`); 43 | })(); 44 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/2.MintingAssets/2.Create.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | percentAmount, 7 | signerIdentity, 8 | some, 9 | } from "@metaplex-foundation/umi"; 10 | import { umiPayer } from "../../lib/umiHelper"; 11 | import { createV1 } from "@metaplex-foundation/mpl-token-metadata"; 12 | import { savePublicKeyToFile } from "../../lib/helpers"; 13 | import { PublicKey } from "@solana/web3.js"; 14 | import { Fungible } from "../1.TokenStandards/TokenStandard"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | // 计算Token Keypair 21 | let tokenMint = generateSigner(umi); 22 | console.log("Mint address:", tokenMint.publicKey); 23 | 24 | await createV1(umi, { 25 | mint: tokenMint, 26 | name: Fungible.name, 27 | symbol: Fungible.symbol, 28 | uri: "https://arweave.net/NoZ4gtzT_kYadwm7d3ArJyROdyuvn6r84KhpIYGHgPw", 29 | sellerFeeBasisPoints: percentAmount(5.5), 30 | decimals: some(9), // for 0 decimals use some(0) 31 | }) 32 | .sendAndConfirm(umi) 33 | .then(({ signature }) => { 34 | txExplorer(signature); 35 | }); 36 | // 保存Token账户地址 37 | savePublicKeyToFile("umi_fungible_token", new PublicKey(tokenMint.publicKey)); 38 | })(); 39 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/2.MintingAssets/3.Mint.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { TokenStandard, mintV1, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | // 读取保存的Token地址 12 | let tokenMint = publicKey(TokenMint("umi_fungible_token")); 13 | 14 | umi.use(mplTokenMetadata()); 15 | await mintV1(umi, { 16 | mint: tokenMint, 17 | tokenOwner: umi.identity.publicKey, 18 | tokenStandard: TokenStandard.Fungible, 19 | amount: 1_000_000_000_000_000_000n, 20 | }) 21 | .sendAndConfirm(umi) 22 | .then(({ signature }) => { 23 | txExplorer(signature); 24 | }); 25 | })(); 26 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/2.MintingAssets/4.CreateNonFungible.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | percentAmount, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { umiPayer } from "../../lib/umiHelper"; 10 | import { createNft, mplTokenMetadata, printSupply } from "@metaplex-foundation/mpl-token-metadata"; 11 | import { savePublicKeyToFile } from "../../lib/helpers"; 12 | import { PublicKey } from "@solana/web3.js"; 13 | import { NonFungible } from "../1.TokenStandards/TokenStandard"; 14 | 15 | (async () => { 16 | const umi = createUmi(CLUSTER_URL); 17 | const signer = createSignerFromKeypair(umi, umiPayer); 18 | umi.use(signerIdentity(signer, true)); 19 | // 计算Token Keypair 20 | let tokenMint = generateSigner(umi); 21 | console.log("Mint address:", tokenMint.publicKey); 22 | umi.use(mplTokenMetadata()); 23 | 24 | await createNft(umi, { 25 | mint: tokenMint, 26 | name: NonFungible.name, 27 | symbol: NonFungible.symbol, 28 | uri: "https://arweave.net/_ShA_RoIEYEj0sVXaZ7t5FvJ-1WqeVt3DZxW1HsLngc", 29 | sellerFeeBasisPoints: percentAmount(5.5), 30 | printSupply: printSupply("Limited", [100]), 31 | isMutable: true, 32 | isCollection: true, 33 | }) 34 | .sendAndConfirm(umi) 35 | .then(({ signature }) => { 36 | txExplorer(signature); 37 | }); 38 | // 保存Token账户地址 39 | savePublicKeyToFile("umi_non_fungible_token", new PublicKey(tokenMint.publicKey)); 40 | })(); 41 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/2.MintingAssets/5.CreateFungible.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | percentAmount, 7 | signerIdentity, 8 | some, 9 | } from "@metaplex-foundation/umi"; 10 | import { umiPayer } from "../../lib/umiHelper"; 11 | import { createFungible, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 12 | import { savePublicKeyToFile } from "../../lib/helpers"; 13 | import { PublicKey } from "@solana/web3.js"; 14 | import { Fungible } from "../1.TokenStandards/TokenStandard"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | // 计算Token Keypair 21 | let tokenMint = generateSigner(umi); 22 | console.log("Mint address:", tokenMint.publicKey); 23 | umi.use(mplTokenMetadata()); 24 | 25 | await createFungible(umi, { 26 | mint: tokenMint, 27 | name: Fungible.name, 28 | symbol: Fungible.symbol, 29 | uri: "https://arweave.net/_ShA_RoIEYEj0sVXaZ7t5FvJ-1WqeVt3DZxW1HsLngc", 30 | sellerFeeBasisPoints: percentAmount(5.5), 31 | decimals: some(7), 32 | }) 33 | .sendAndConfirm(umi) 34 | .then(({ signature }) => { 35 | txExplorer(signature); 36 | }); 37 | // 保存Token账户地址 38 | savePublicKeyToFile("umi_fungible_token", new PublicKey(tokenMint.publicKey)); 39 | })(); 40 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/2.MintingAssets/6.CreateFungibleAsset.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | percentAmount, 7 | signerIdentity, 8 | some, 9 | } from "@metaplex-foundation/umi"; 10 | import { umiPayer } from "../../lib/umiHelper"; 11 | import { createFungibleAsset, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 12 | import { savePublicKeyToFile } from "../../lib/helpers"; 13 | import { PublicKey } from "@solana/web3.js"; 14 | import { FungibleAsset } from "../1.TokenStandards/TokenStandard"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | // 计算Token Keypair 21 | let tokenMint = generateSigner(umi); 22 | console.log("Mint address:", tokenMint.publicKey); 23 | umi.use(mplTokenMetadata()); 24 | 25 | await createFungibleAsset(umi, { 26 | mint: tokenMint, 27 | name: FungibleAsset.name, 28 | symbol: FungibleAsset.symbol, 29 | uri: FungibleAsset.external_url, 30 | sellerFeeBasisPoints: percentAmount(5.5), 31 | decimals: some(7), 32 | }) 33 | .sendAndConfirm(umi) 34 | .then(({ signature }) => { 35 | txExplorer(signature); 36 | }); 37 | // 保存Token账户地址 38 | savePublicKeyToFile("umi_fungible_asset_token", new PublicKey(tokenMint.publicKey)); 39 | })(); 40 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/2.MintingAssets/7.CreateProgrammableNft.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | percentAmount, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { umiPayer } from "../../lib/umiHelper"; 10 | import { createProgrammableNft, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 11 | import { savePublicKeyToFile } from "../../lib/helpers"; 12 | import { PublicKey } from "@solana/web3.js"; 13 | import { ProgramableNonFungible } from "../1.TokenStandards/TokenStandard"; 14 | 15 | (async () => { 16 | const umi = createUmi(CLUSTER_URL); 17 | const signer = createSignerFromKeypair(umi, umiPayer); 18 | umi.use(signerIdentity(signer, true)); 19 | // 计算Token Keypair 20 | let tokenMint = generateSigner(umi); 21 | console.log("Mint address:", tokenMint.publicKey); 22 | umi.use(mplTokenMetadata()); 23 | 24 | await createProgrammableNft(umi, { 25 | mint: tokenMint, 26 | name: ProgramableNonFungible.name, 27 | uri: ProgramableNonFungible.external_url, 28 | sellerFeeBasisPoints: percentAmount(5.5), 29 | }) 30 | .sendAndConfirm(umi) 31 | .then(({ signature }) => { 32 | txExplorer(signature); 33 | }); 34 | // 保存Token账户地址 35 | savePublicKeyToFile("umi_ProgramableNonFungibl_token", new PublicKey(tokenMint.publicKey)); 36 | })(); 37 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/1.FetchDigitalAsset.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchDigitalAsset } from "@metaplex-foundation/mpl-token-metadata"; 6 | (async () => { 7 | const umi = createUmi(CLUSTER_URL); 8 | const signer = createSignerFromKeypair(umi, umiPayer); 9 | umi.use(signerIdentity(signer, true)); 10 | // 读取保存的Token地址 11 | let mint = publicKey(TokenMint("umi_fungible_token")); 12 | 13 | let ret = await fetchDigitalAsset(umi, mint); 14 | console.log(ret); 15 | })(); 16 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/10.FetchAllDigitalAssetWithTokenByMint.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchAllDigitalAssetWithTokenByMint } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | // 读取保存的Token地址 12 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 13 | 14 | let ret = await fetchAllDigitalAssetWithTokenByMint(umi, mint); 15 | console.log(ret); 16 | })(); 17 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/11.FetchAllDigitalAssetWithTokenByOwnerAndMint.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchAllDigitalAssetWithTokenByOwnerAndMint } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | // 读取保存的Token地址 12 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 13 | 14 | let ret = await fetchAllDigitalAssetWithTokenByOwnerAndMint(umi, signer.publicKey, mint); 15 | console.log(ret); 16 | })(); 17 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/2.FetchDigitalAssetByMetadata.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchDigitalAssetByMetadata } from "@metaplex-foundation/mpl-token-metadata"; 6 | const metadata = publicKey("9aRXDXKC3z7zEMTXjrrZFR8SN9uPwkFkbw2bA2jeCrQ9"); 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | 12 | let ret = await fetchDigitalAssetByMetadata(umi, metadata); 13 | console.log(ret); 14 | })(); 15 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/3.FetchAllDigitalAsset.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchAllDigitalAsset } from "@metaplex-foundation/mpl-token-metadata"; 6 | (async () => { 7 | const umi = createUmi(CLUSTER_URL); 8 | const signer = createSignerFromKeypair(umi, umiPayer); 9 | umi.use(signerIdentity(signer, true)); 10 | // 读取保存的Token地址 11 | let mint1 = publicKey(TokenMint("umi_fungible_token")); 12 | let mint2 = publicKey(TokenMint("umi_non_fungible_token")); 13 | 14 | let ret = await fetchAllDigitalAsset(umi, [mint1, mint2]); 15 | console.log(ret); 16 | })(); 17 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/4.FetchAllDigitalAssetByCreator.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL } from "../../lib/vars"; 3 | import { createSignerFromKeypair, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchAllDigitalAssetByCreator } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | 12 | let ret = await fetchAllDigitalAssetByCreator(umi, signer.publicKey); 13 | console.log(ret); 14 | })(); 15 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/5.FetchAllDigitalAssetByOwner.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL } from "../../lib/vars"; 3 | import { createSignerFromKeypair, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchAllDigitalAssetByOwner } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | 12 | let ret = await fetchAllDigitalAssetByOwner(umi, signer.publicKey); 13 | console.log(ret); 14 | })(); 15 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/6.FetchAllDigitalAssetByUpdateAuthority.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL } from "../../lib/vars"; 3 | import { createSignerFromKeypair, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchAllDigitalAssetByUpdateAuthority } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | 12 | let ret = await fetchAllDigitalAssetByUpdateAuthority(umi, signer.publicKey); 13 | console.log(ret); 14 | })(); 15 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/7.FetchDigitalAssetWithTokenByMint.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchDigitalAssetWithTokenByMint } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | // 读取保存的Token地址 12 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 13 | 14 | let ret = await fetchDigitalAssetWithTokenByMint(umi, mint); 15 | console.log(ret); 16 | })(); 17 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/8.FetchDigitalAssetWithAssociatedToken.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { 6 | fetchDigitalAssetWithAssociatedToken, 7 | mplTokenMetadata, 8 | } from "@metaplex-foundation/mpl-token-metadata"; 9 | 10 | (async () => { 11 | const umi = createUmi(CLUSTER_URL); 12 | const signer = createSignerFromKeypair(umi, umiPayer); 13 | umi.use(signerIdentity(signer, true)); 14 | umi.use(mplTokenMetadata()); 15 | // 读取保存的Token地址 16 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 17 | 18 | let ret = await fetchDigitalAssetWithAssociatedToken(umi, mint, signer.publicKey); 19 | console.log(ret); 20 | })(); 21 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/3.FetchingAssets/9.FetchAllDigitalAssetWithTokenByOwner.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL } from "../../lib/vars"; 3 | import { createSignerFromKeypair, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchAllDigitalAssetWithTokenByOwner } from "@metaplex-foundation/mpl-token-metadata"; 6 | 7 | (async () => { 8 | const umi = createUmi(CLUSTER_URL); 9 | const signer = createSignerFromKeypair(umi, umiPayer); 10 | umi.use(signerIdentity(signer, true)); 11 | 12 | let ret = await fetchAllDigitalAssetWithTokenByOwner(umi, signer.publicKey); 13 | console.log(ret); 14 | })(); 15 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/4.UpdatingAssets/1.UpdateTokenMetadata.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { fetchMetadataFromSeeds, updateV1 } from "@metaplex-foundation/mpl-token-metadata"; 6 | import { publicKey } from "@metaplex-foundation/umi"; 7 | 8 | (async () => { 9 | const umi = createUmi(CLUSTER_URL); 10 | const signer = createSignerFromKeypair(umi, umiPayer); 11 | umi.use(signerIdentity(signer, true)); 12 | // 读取保存的Token地址 13 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 14 | const initialMetadata = await fetchMetadataFromSeeds(umi, { mint }); 15 | 16 | await updateV1(umi, { 17 | mint: mint, 18 | data: { ...initialMetadata, name: "Updated Assets" }, 19 | primarySaleHappened: true, 20 | isMutable: false, 21 | }) 22 | .sendAndConfirm(umi) 23 | .then(({ signature }) => { 24 | txExplorer(signature); 25 | }); 26 | })(); 27 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/5.TransferringAssets/1.Transfer.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, generateSigner, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { 6 | TokenStandard, 7 | mplTokenMetadata, 8 | transferV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | import { publicKey } from "@metaplex-foundation/umi"; 11 | 12 | (async () => { 13 | const umi = createUmi(CLUSTER_URL); 14 | const signer = createSignerFromKeypair(umi, umiPayer); 15 | umi.use(signerIdentity(signer, true)); 16 | umi.use(mplTokenMetadata()); 17 | // 读取保存的Token地址 18 | let mint = publicKey(TokenMint("umi_fungible_token")); 19 | let receiver = generateSigner(umi); 20 | 21 | await transferV1(umi, { 22 | mint: mint, 23 | authority: signer, 24 | tokenOwner: signer.publicKey, 25 | destinationOwner: receiver.publicKey, 26 | tokenStandard: TokenStandard.Fungible, 27 | amount: 1_000_000_000, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/6.BurningAssets/1.Burn.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { TokenStandard, burnV1, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 6 | import { publicKey } from "@metaplex-foundation/umi"; 7 | 8 | (async () => { 9 | const umi = createUmi(CLUSTER_URL); 10 | const signer = createSignerFromKeypair(umi, umiPayer); 11 | umi.use(signerIdentity(signer, true)); 12 | umi.use(mplTokenMetadata()); 13 | // 读取保存的Token地址 14 | let mint = publicKey(TokenMint("umi_non_fungible_token")); 15 | 16 | await burnV1(umi, { 17 | mint: mint, 18 | authority: signer, 19 | tokenOwner: signer.publicKey, 20 | tokenStandard: TokenStandard.NonFungible, 21 | }) 22 | .sendAndConfirm(umi) 23 | .then(({ signature }) => { 24 | txExplorer(signature); 25 | }); 26 | })(); 27 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/7.PrintedEditions/1.Print.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | publicKey, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { umiPayer } from "../../lib/umiHelper"; 10 | import { 11 | TokenStandard, 12 | fetchMasterEditionFromSeeds, 13 | mplTokenMetadata, 14 | printV1, 15 | } from "@metaplex-foundation/mpl-token-metadata"; 16 | 17 | (async () => { 18 | // 初始化 19 | const umi = createUmi(CLUSTER_URL); 20 | // 获取签名人 21 | const signer = createSignerFromKeypair(umi, umiPayer); 22 | umi.use(signerIdentity(signer, true)); 23 | umi.use(mplTokenMetadata()); 24 | // 读取保存的Token地址 25 | let masterEditionMint = publicKey(TokenMint("umi_non_fungible_token")); 26 | // 随机计算接受者 27 | let receiver = generateSigner(umi); 28 | // 获取masterEdition数据 29 | const masterEdition = await fetchMasterEditionFromSeeds(umi, { 30 | mint: masterEditionMint, 31 | }); 32 | console.log("masterEdition:", masterEdition.publicKey); 33 | // 随机计算editionMint地址 34 | const editionMint = generateSigner(umi); 35 | console.log("editionMint:", editionMint.publicKey); 36 | // 打印 37 | await printV1(umi, { 38 | masterTokenAccountOwner: signer, 39 | masterEditionMint: masterEditionMint, 40 | editionMint, 41 | editionTokenAccountOwner: receiver.publicKey, 42 | editionNumber: masterEdition.supply + 1n, 43 | tokenStandard: TokenStandard.NonFungible, 44 | }) 45 | .sendAndConfirm(umi) 46 | .then(({ signature }) => { 47 | txExplorer(signature); 48 | }); 49 | })(); 50 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/8.VerifiedCollections/0.CreateCollection.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | percentAmount, 7 | signerIdentity, 8 | } from "@metaplex-foundation/umi"; 9 | import { umiPayer } from "../../lib/umiHelper"; 10 | import { createNft, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 11 | import { savePublicKeyToFile } from "../../lib/helpers"; 12 | import { PublicKey } from "@solana/web3.js"; 13 | import { NonFungible } from "../1.TokenStandards/TokenStandard"; 14 | 15 | (async () => { 16 | const umi = createUmi(CLUSTER_URL); 17 | const signer = createSignerFromKeypair(umi, umiPayer); 18 | umi.use(signerIdentity(signer, true)); 19 | umi.use(mplTokenMetadata()); 20 | // 计算Token Keypair 21 | let collectionMint = generateSigner(umi); 22 | console.log("Collection Mint address:", collectionMint.publicKey); 23 | // 保存Token账户地址 24 | savePublicKeyToFile("umi_collection", new PublicKey(collectionMint.publicKey)); 25 | 26 | await createNft(umi, { 27 | mint: collectionMint, 28 | name: NonFungible.name, 29 | symbol: NonFungible.symbol, 30 | uri: "https://arweave.net/_ShA_RoIEYEj0sVXaZ7t5FvJ-1WqeVt3DZxW1HsLngc", 31 | sellerFeeBasisPoints: percentAmount(5.5), 32 | isMutable: false, 33 | isCollection: true, 34 | }) 35 | .sendAndConfirm(umi) 36 | .then(({ signature }) => { 37 | txExplorer(signature); 38 | }); 39 | })(); 40 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/8.VerifiedCollections/1.CreateCollectionNFT.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { 4 | createSignerFromKeypair, 5 | generateSigner, 6 | percentAmount, 7 | publicKey, 8 | signerIdentity, 9 | } from "@metaplex-foundation/umi"; 10 | import { umiPayer } from "../../lib/umiHelper"; 11 | import { createNft, mplTokenMetadata } from "@metaplex-foundation/mpl-token-metadata"; 12 | import { savePublicKeyToFile } from "../../lib/helpers"; 13 | import { PublicKey } from "@solana/web3.js"; 14 | import { NonFungible } from "../1.TokenStandards/TokenStandard"; 15 | 16 | (async () => { 17 | const umi = createUmi(CLUSTER_URL); 18 | const signer = createSignerFromKeypair(umi, umiPayer); 19 | umi.use(signerIdentity(signer, true)); 20 | umi.use(mplTokenMetadata()); 21 | // 读取保存的Token地址 22 | let collectionMint = publicKey(TokenMint("umi_collection")); 23 | // 计算Token Keypair 24 | let collectionNFTMint = generateSigner(umi); 25 | console.log("Collection NFT Mint address:", collectionNFTMint.publicKey); 26 | // 保存Token账户地址 27 | savePublicKeyToFile("umi_collection_NFT", new PublicKey(collectionNFTMint.publicKey)); 28 | 29 | await createNft(umi, { 30 | mint: collectionNFTMint, 31 | name: NonFungible.name, 32 | symbol: NonFungible.symbol, 33 | uri: "https://arweave.net/_ShA_RoIEYEj0sVXaZ7t5FvJ-1WqeVt3DZxW1HsLngc", 34 | sellerFeeBasisPoints: percentAmount(5.5), 35 | isMutable: true, 36 | collection: { 37 | verified: false, 38 | key: collectionMint, 39 | }, 40 | }) 41 | .sendAndConfirm(umi) 42 | .then(({ signature }) => { 43 | txExplorer(signature); 44 | }); 45 | })(); 46 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/8.VerifiedCollections/2.VerifyCollection.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { 6 | findMetadataPda, 7 | mplTokenMetadata, 8 | verifyCollectionV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | // 读取保存的Token地址 17 | let collectionMint = publicKey(TokenMint("umi_collection")); 18 | // 读取保存的Token地址 19 | let collectionNFTMint = publicKey(TokenMint("umi_collection_NFT")); 20 | 21 | const metadata = findMetadataPda(umi, { 22 | mint: collectionNFTMint, 23 | }); 24 | console.log("metadata:", metadata[0]); 25 | 26 | await verifyCollectionV1(umi, { 27 | metadata: metadata, 28 | collectionMint: collectionMint, 29 | authority: signer, 30 | }) 31 | .sendAndConfirm(umi) 32 | .then(({ signature }) => { 33 | txExplorer(signature); 34 | }); 35 | })(); 36 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/8.VerifiedCollections/3.UnVerifyCollection.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { 6 | findMetadataPda, 7 | mplTokenMetadata, 8 | unverifyCollectionV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | // 读取保存的Token地址 17 | let collectionMint = publicKey(TokenMint("umi_collection")); 18 | // 读取保存的Token地址 19 | let collectionNFTMint = publicKey(TokenMint("umi_collection_NFT")); 20 | 21 | const metadata = findMetadataPda(umi, { 22 | mint: collectionNFTMint, 23 | }); 24 | console.log("metadata:", metadata[0]); 25 | 26 | await unverifyCollectionV1(umi, { 27 | metadata: metadata, 28 | collectionMint: collectionMint, 29 | authority: signer, 30 | }) 31 | .sendAndConfirm(umi) 32 | .then(({ signature }) => { 33 | txExplorer(signature); 34 | }); 35 | })(); 36 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/9.VerifiedCreators/1.VerifyCreator.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { 6 | findMetadataPda, 7 | mplTokenMetadata, 8 | verifyCreatorV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Token地址 18 | let collectionNFTMint = publicKey(TokenMint("umi_collection_NFT")); 19 | 20 | const metadata = findMetadataPda(umi, { 21 | mint: collectionNFTMint, 22 | }); 23 | console.log("metadata:", metadata[0]); 24 | 25 | await verifyCreatorV1(umi, { 26 | metadata: metadata, 27 | authority: signer, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/5.UmiTokenMetadata/9.VerifiedCreators/2.UnVerifyCreator.ts: -------------------------------------------------------------------------------- 1 | import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; 2 | import { CLUSTER_URL, TokenMint, txExplorer } from "../../lib/vars"; 3 | import { createSignerFromKeypair, publicKey, signerIdentity } from "@metaplex-foundation/umi"; 4 | import { umiPayer } from "../../lib/umiHelper"; 5 | import { 6 | findMetadataPda, 7 | mplTokenMetadata, 8 | unverifyCreatorV1, 9 | } from "@metaplex-foundation/mpl-token-metadata"; 10 | 11 | (async () => { 12 | const umi = createUmi(CLUSTER_URL); 13 | const signer = createSignerFromKeypair(umi, umiPayer); 14 | umi.use(signerIdentity(signer, true)); 15 | umi.use(mplTokenMetadata()); 16 | 17 | // 读取保存的Token地址 18 | let collectionNFTMint = publicKey(TokenMint("umi_collection_NFT")); 19 | 20 | const metadata = findMetadataPda(umi, { 21 | mint: collectionNFTMint, 22 | }); 23 | console.log("metadata:", metadata[0]); 24 | 25 | await unverifyCreatorV1(umi, { 26 | metadata: metadata, 27 | authority: signer, 28 | }) 29 | .sendAndConfirm(umi) 30 | .then(({ signature }) => { 31 | txExplorer(signature); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /scripts/lib/helpers.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | import { 4 | Connection, 5 | Keypair, 6 | LAMPORTS_PER_SOL, 7 | PublicKey, 8 | TransactionInstruction, 9 | TransactionMessage, 10 | VersionedTransaction, 11 | } from "@solana/web3.js"; 12 | 13 | // define some default locations 14 | const DEFAULT_KEY_DIR_NAME = ".local_keys"; 15 | const DEFAULT_PUBLIC_KEY_FILE = "keys.json"; 16 | const DEFAULT_DEMO_DATA_FILE = "demo.json"; 17 | 18 | /** 19 | * Load locally stored PublicKey addresses 20 | */ 21 | export function loadPublicKeysFromFile( 22 | absPath: string = `${DEFAULT_KEY_DIR_NAME}/${DEFAULT_PUBLIC_KEY_FILE}`, 23 | ) { 24 | try { 25 | if (!absPath) throw Error("No path provided"); 26 | if (!fs.existsSync(absPath)) throw Error("File does not exist."); 27 | 28 | // load the public keys from the file 29 | const data = JSON.parse(fs.readFileSync(absPath, { encoding: "utf-8" })) || {}; 30 | 31 | // convert all loaded keyed values into valid public keys 32 | for (const [key, value] of Object.entries(data)) { 33 | data[key] = new PublicKey(value as string) ?? ""; 34 | } 35 | 36 | return data; 37 | } catch (err) { 38 | // console.warn("Unable to load local file"); 39 | } 40 | // always return an object 41 | return {}; 42 | } 43 | 44 | /* 45 | Locally save a demo data to the filesystem for later retrieval 46 | */ 47 | export function saveDemoDataToFile( 48 | name: string, 49 | newData: any, 50 | absPath: string = `${DEFAULT_KEY_DIR_NAME}/${DEFAULT_DEMO_DATA_FILE}`, 51 | ) { 52 | try { 53 | let data: object = {}; 54 | 55 | // fetch all the current values, when the storage file exists 56 | if (fs.existsSync(absPath)) 57 | data = JSON.parse(fs.readFileSync(absPath, { encoding: "utf-8" })) || {}; 58 | 59 | data = { ...data, [name]: newData }; 60 | 61 | // actually save the data to the file 62 | fs.writeFileSync(absPath, JSON.stringify(data), { 63 | encoding: "utf-8", 64 | }); 65 | 66 | return data; 67 | } catch (err) { 68 | console.warn("Unable to save to file"); 69 | // console.warn(err); 70 | } 71 | 72 | // always return an object 73 | return {}; 74 | } 75 | 76 | /* 77 | Locally save a PublicKey addresses to the filesystem for later retrieval 78 | */ 79 | export function savePublicKeyToFile( 80 | name: string, 81 | publicKey: PublicKey, 82 | absPath: string = `${DEFAULT_KEY_DIR_NAME}/${DEFAULT_PUBLIC_KEY_FILE}`, 83 | ) { 84 | try { 85 | // if (!absPath) throw Error("No path provided"); 86 | // if (!fs.existsSync(absPath)) throw Error("File does not exist."); 87 | 88 | // fetch all the current values 89 | let data: any = loadPublicKeysFromFile(absPath); 90 | 91 | // convert all loaded keyed values from PublicKeys to strings 92 | for (const [key, value] of Object.entries(data)) { 93 | data[key as any] = (value as PublicKey).toBase58(); 94 | } 95 | data = { ...data, [name]: publicKey.toBase58() }; 96 | 97 | // actually save the data to the file 98 | fs.writeFileSync(absPath, JSON.stringify(data), { 99 | encoding: "utf-8", 100 | }); 101 | 102 | // reload the keys for sanity 103 | data = loadPublicKeysFromFile(absPath); 104 | 105 | return data; 106 | } catch (err) { 107 | console.warn("Unable to save to file"); 108 | } 109 | // always return an object 110 | return {}; 111 | } 112 | 113 | /* 114 | Load a locally stored JSON keypair file and convert it to a valid Keypair 115 | */ 116 | export function loadKeypairFromFile(absPath: string) { 117 | try { 118 | if (!absPath) throw Error("No path provided"); 119 | if (!fs.existsSync(absPath)) throw Error("File does not exist."); 120 | 121 | // load the keypair from the file 122 | const keyfileBytes = JSON.parse(fs.readFileSync(absPath, { encoding: "utf-8" })); 123 | // parse the loaded secretKey into a valid keypair 124 | const keypair = Keypair.fromSecretKey(new Uint8Array(keyfileBytes)); 125 | return keypair; 126 | } catch (err) { 127 | // return false; 128 | throw err; 129 | } 130 | } 131 | 132 | /* 133 | Save a locally stored JSON keypair file for later importing 134 | */ 135 | export function saveKeypairToFile( 136 | keypair: Keypair, 137 | fileName: string, 138 | dirName: string = DEFAULT_KEY_DIR_NAME, 139 | ) { 140 | fileName = path.join(dirName, `${fileName}.json`); 141 | 142 | // create the `dirName` directory, if it does not exists 143 | if (!fs.existsSync(`./${dirName}/`)) fs.mkdirSync(`./${dirName}/`); 144 | 145 | // remove the current file, if it already exists 146 | if (fs.existsSync(fileName)) fs.unlinkSync(fileName); 147 | 148 | // write the `secretKey` value as a string 149 | fs.writeFileSync(fileName, `[${keypair.secretKey.toString()}]`, { 150 | encoding: "utf-8", 151 | }); 152 | 153 | return fileName; 154 | } 155 | 156 | /* 157 | Attempt to load a keypair from the filesystem, or generate and save a new one 158 | */ 159 | export function loadOrGenerateKeypair(fileName: string, dirName: string = DEFAULT_KEY_DIR_NAME) { 160 | try { 161 | // compute the path to locate the file 162 | const searchPath = path.join(dirName, `${fileName}.json`); 163 | let keypair = Keypair.generate(); 164 | 165 | // attempt to load the keypair from the file 166 | if (fs.existsSync(searchPath)) keypair = loadKeypairFromFile(searchPath); 167 | // when unable to locate the keypair, save the new one 168 | else saveKeypairToFile(keypair, fileName, dirName); 169 | 170 | return keypair; 171 | } catch (err) { 172 | console.error("loadOrGenerateKeypair:", err); 173 | throw err; 174 | } 175 | } 176 | 177 | /* 178 | Compute the Solana explorer address for the various data 179 | */ 180 | export function explorerURL({ 181 | address, 182 | txSignature, 183 | cluster, 184 | }: { 185 | address?: string; 186 | txSignature?: string; 187 | cluster?: "devnet" | "testnet" | "mainnet" | "mainnet-beta"; 188 | }) { 189 | let baseUrl: string; 190 | // 191 | if (address) baseUrl = `https://explorer.solana.com/address/${address}`; 192 | else if (txSignature) baseUrl = `https://explorer.solana.com/tx/${txSignature}`; 193 | else return "[unknown]"; 194 | 195 | // auto append the desired search params 196 | const url = new URL(baseUrl); 197 | url.searchParams.append("cluster", cluster || "devnet"); 198 | return url.toString() + "\n"; 199 | } 200 | 201 | /** 202 | * Auto airdrop the given wallet of of a balance of < 0.5 SOL 203 | */ 204 | export async function airdropOnLowBalance( 205 | connection: Connection, 206 | keypair: Keypair, 207 | forceAirdrop: boolean = false, 208 | ) { 209 | // get the current balance 210 | let balance = await connection.getBalance(keypair.publicKey); 211 | 212 | // define the low balance threshold before airdrop 213 | const MIN_BALANCE_TO_AIRDROP = LAMPORTS_PER_SOL / 2; // current: 0.5 SOL 214 | 215 | // check the balance of the two accounts, airdrop when low 216 | if (forceAirdrop === true || balance < MIN_BALANCE_TO_AIRDROP) { 217 | console.log(`Requesting airdrop of 1 SOL to ${keypair.publicKey.toBase58()}...`); 218 | await connection.requestAirdrop(keypair.publicKey, LAMPORTS_PER_SOL).then(sig => { 219 | console.log("Tx signature:", sig); 220 | // balance = balance + LAMPORTS_PER_SOL; 221 | }); 222 | 223 | // fetch the new balance 224 | // const newBalance = await connection.getBalance(keypair.publicKey); 225 | // return newBalance; 226 | } 227 | // else console.log("Balance of:", balance / LAMPORTS_PER_SOL, "SOL"); 228 | 229 | return balance; 230 | } 231 | 232 | /* 233 | Helper function to extract a transaction signature from a failed transaction's error message 234 | */ 235 | export async function extractSignatureFromFailedTransaction( 236 | connection: Connection, 237 | err: any, 238 | fetchLogs?: boolean, 239 | ) { 240 | if (err?.signature) return err.signature; 241 | 242 | // extract the failed transaction's signature 243 | const failedSig = new RegExp(/^((.*)?Error: )?(Transaction|Signature) ([A-Z0-9]{32,}) /gim).exec( 244 | err?.message?.toString(), 245 | )?.[4]; 246 | 247 | // ensure a signature was found 248 | if (failedSig) { 249 | // when desired, attempt to fetch the program logs from the cluster 250 | if (fetchLogs) 251 | await connection 252 | .getTransaction(failedSig, { 253 | maxSupportedTransactionVersion: 0, 254 | }) 255 | .then(tx => { 256 | console.log(`\n==== Transaction logs for ${failedSig} ====`); 257 | console.log(explorerURL({ txSignature: failedSig }), ""); 258 | console.log(tx?.meta?.logMessages ?? "No log messages provided by RPC"); 259 | console.log(`==== END LOGS ====\n`); 260 | }); 261 | else { 262 | console.log("\n========================================"); 263 | console.log(explorerURL({ txSignature: failedSig })); 264 | console.log("========================================\n"); 265 | } 266 | } 267 | 268 | // always return the failed signature value 269 | return failedSig; 270 | } 271 | 272 | /* 273 | Standard number formatter 274 | */ 275 | export function numberFormatter(num: number, forceDecimals = false) { 276 | // set the significant figures 277 | const minimumFractionDigits = num < 1 || forceDecimals ? 10 : 2; 278 | 279 | // do the formatting 280 | return new Intl.NumberFormat(undefined, { 281 | minimumFractionDigits, 282 | }).format(num); 283 | } 284 | 285 | /* 286 | Display a separator in the console, with our without a message 287 | */ 288 | export function printConsoleSeparator(message?: string) { 289 | console.log("\n==============================================="); 290 | console.log("===============================================\n"); 291 | if (message) console.log(message); 292 | } 293 | 294 | /** 295 | * Helper function to build a signed transaction 296 | */ 297 | export async function buildTransaction({ 298 | connection, 299 | payer, 300 | signers, 301 | instructions, 302 | }: { 303 | connection: Connection; 304 | payer: PublicKey; 305 | signers: Keypair[]; 306 | instructions: TransactionInstruction[]; 307 | }): Promise { 308 | let blockhash = await connection.getLatestBlockhash().then(res => res.blockhash); 309 | 310 | const messageV0 = new TransactionMessage({ 311 | payerKey: payer, 312 | recentBlockhash: blockhash, 313 | instructions, 314 | }).compileToV0Message(); 315 | 316 | const tx = new VersionedTransaction(messageV0); 317 | 318 | signers.forEach(s => tx.sign([s])); 319 | 320 | return tx; 321 | } 322 | -------------------------------------------------------------------------------- /scripts/lib/umiHelper.ts: -------------------------------------------------------------------------------- 1 | import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters"; 2 | import path from "path"; 3 | import fs from "fs"; 4 | import { Keypair } from "@solana/web3.js"; 5 | 6 | const DEFAULT_KEY_DIR_NAME = ".local_keys"; 7 | export function UmiKeypair(fileName: string, dirName: string = DEFAULT_KEY_DIR_NAME) { 8 | try { 9 | // compute the path to locate the file 10 | const searchPath = path.join(dirName, `${fileName}.json`); 11 | const loaded = Keypair.fromSecretKey( 12 | new Uint8Array(JSON.parse(fs.readFileSync(searchPath).toString())), 13 | ); 14 | 15 | return fromWeb3JsKeypair(loaded); 16 | } catch (err) { 17 | console.error("loadOrGenerateKeypair:", err); 18 | throw err; 19 | } 20 | } 21 | 22 | export const umiPayer = UmiKeypair("payer"); 23 | -------------------------------------------------------------------------------- /scripts/lib/vars.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import { PublicKey, Connection, clusterApiUrl } from "@solana/web3.js"; 3 | import { explorerURL, loadOrGenerateKeypair, loadPublicKeysFromFile } from "./helpers"; 4 | import { RpcConfirmTransactionResult } from "@metaplex-foundation/umi"; 5 | import base58 from "bs58"; 6 | 7 | // load the env variables from file 8 | dotenv.config(); 9 | 10 | export const FgGreen = "\x1b[32m"; 11 | export const FgRed = "\x1b[31m"; 12 | export const FgYellow = "\x1b[33m"; 13 | /** 14 | * Load the `payer` keypair from the local file system, or load/generate a new 15 | * one and storing it within the local directory 16 | */ 17 | export const payer = loadOrGenerateKeypair("Payer"); 18 | 19 | // generate a new Keypair for testing, named `wallet` 20 | export const testWallet = loadOrGenerateKeypair("testWallet"); 21 | 22 | // load the env variables and store the cluster RPC url 23 | export const CLUSTER_URL = process.env.RPC_URL ?? clusterApiUrl("devnet"); 24 | 25 | // create a new rpc connection 26 | export const connection = new Connection(CLUSTER_URL, "confirmed"); 27 | 28 | // define an address to also transfer lamports too 29 | export const STATIC_PUBLICKEY = new PublicKey("nickb1dAk4hKpHVPZenpzqVtw2F8RHnCq27QcfiReXD"); 30 | 31 | export function TokenMint(symble: string) { 32 | // load the stored PublicKeys for ease of use 33 | let localKeys = loadPublicKeysFromFile(); 34 | 35 | const tokenMint: PublicKey = localKeys[symble]; 36 | 37 | console.log(FgGreen + "==== Local PublicKeys loaded ===="); 38 | console.log(`${FgGreen}Token's mint address: ${FgYellow + tokenMint}`); 39 | console.log(FgYellow + explorerURL({ address: tokenMint.toString() })); 40 | return tokenMint; 41 | } 42 | 43 | export function txExplorer(signature: Uint8Array) { 44 | console.log(FgYellow + explorerURL({ txSignature: base58.encode(signature) })); 45 | } 46 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "commonjs", 5 | "strict": true, 6 | "preserveConstEnums": true, 7 | "noEmit": true, 8 | "sourceMap": false, 9 | "moduleResolution": "node", 10 | "esModuleInterop": true, 11 | "skipLibCheck": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "allowJs": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "incremental": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@/*": ["./*"] 20 | } 21 | }, 22 | "include": ["**/*.ts", "**/**.ts", "**/*.tsx"], 23 | "exclude": ["node_modules", ".vscode"] 24 | } 25 | --------------------------------------------------------------------------------