1- import { PublicKey , Transaction , TransactionInstruction } from '@solana/web3.js'
1+ import {
2+ Connection ,
3+ Keypair ,
4+ PublicKey ,
5+ Transaction ,
6+ TransactionInstruction ,
7+ } from '@solana/web3.js'
28import BN from 'bn.js'
39import { MintMaxVoteWeightSource } from '../models/accounts'
410import { withCreateRealm } from '../models/withCreateRealm'
511import { RpcContext } from '../models/core/api'
612import { sendTransaction } from '../utils/send'
713import { ProgramVersion } from '@models/registry/constants'
14+ import { sendTransactions , SequenceType } from 'utils/sendTransactions'
15+ import { withCreateMint } from '@tools/sdk/splToken/withCreateMint'
16+ import { withCreateAssociatedTokenAccount } from '@tools/sdk/splToken/withCreateAssociatedTokenAccount'
17+ import { withMintTo } from '@tools/sdk/splToken/withMintTo'
18+ import { chunks } from '@utils/helpers'
19+ import { WalletConnectionError } from '@solana/wallet-adapter-base'
20+ import { withDepositGoverningTokens } from '@models/withDepositGoverningTokens'
21+
22+ /**
23+ * Prepares the council instructions
24+ * @param connection
25+ * @param walletPubkey
26+ * @param councilMint
27+ * @param councilWalletPks
28+ */
29+ async function prepareCouncilInstructions (
30+ connection : Connection ,
31+ walletPubkey : PublicKey ,
32+ councilMint ?: PublicKey ,
33+ councilWalletPks ?: PublicKey [ ]
34+ ) {
35+ let councilMintPk : PublicKey | undefined = undefined
36+ let walletAtaPk : PublicKey | undefined
37+ const councilMintInstructions : TransactionInstruction [ ] = [ ]
38+ const councilMintSigners : Keypair [ ] = [ ]
39+
40+ // If the array of council wallets is not empty
41+ // then should create mints to the council
42+ if ( councilWalletPks && councilWalletPks . length ) {
43+ // If councilMint is undefined, then
44+ // should create the council mint
45+ councilMintPk =
46+ councilMint ??
47+ ( await withCreateMint (
48+ connection ,
49+ councilMintInstructions ,
50+ councilMintSigners ,
51+ walletPubkey ,
52+ null ,
53+ 0 ,
54+ walletPubkey
55+ ) )
56+
57+ for ( const teamWalletPk of councilWalletPks ) {
58+ const ataPk = await withCreateAssociatedTokenAccount (
59+ councilMintInstructions ,
60+ councilMintPk ,
61+ teamWalletPk ,
62+ walletPubkey
63+ )
64+
65+ // Mint 1 council token to each team member
66+ await withMintTo (
67+ councilMintInstructions ,
68+ councilMintPk ,
69+ ataPk ,
70+ walletPubkey ,
71+ 1
72+ )
73+
74+ if ( teamWalletPk . equals ( walletPubkey ) ) {
75+ walletAtaPk = ataPk
76+ }
77+ }
78+ }
79+
80+ const councilMembersChunks = chunks ( councilMintInstructions , 10 )
81+ // only walletPk needs to sign the minting instructions and it's a signer by default and we don't have to include any more signers
82+ const councilSignersChunks = Array ( councilMembersChunks . length ) . fill (
83+ councilMintSigners
84+ )
85+
86+ return {
87+ councilMintPk,
88+ walletAtaPk,
89+ councilMembersChunks,
90+ councilSignersChunks,
91+ }
92+ }
893
994export async function registerRealm (
1095 { connection, wallet, walletPubkey } : RpcContext ,
@@ -14,27 +99,72 @@ export async function registerRealm(
1499 communityMint : PublicKey ,
15100 councilMint : PublicKey | undefined ,
16101 communityMintMaxVoteWeightSource : MintMaxVoteWeightSource ,
17- minCommunityTokensToCreateGovernance : BN
102+ minCommunityTokensToCreateGovernance : BN ,
103+ councilWalletPks ?: PublicKey [ ]
18104) : Promise < PublicKey > {
19- const instructions : TransactionInstruction [ ] = [ ]
105+ const realmInstructions : TransactionInstruction [ ] = [ ]
106+
107+ const {
108+ councilMintPk,
109+ walletAtaPk,
110+ councilMembersChunks,
111+ councilSignersChunks,
112+ } = await prepareCouncilInstructions (
113+ connection ,
114+ walletPubkey ,
115+ councilMint ,
116+ councilWalletPks
117+ )
20118
21119 const realmAddress = await withCreateRealm (
22- instructions ,
120+ realmInstructions ,
23121 programId ,
24122 programVersion ,
25123 name ,
26124 walletPubkey ,
27125 communityMint ,
28126 walletPubkey ,
29- councilMint ,
127+ councilMintPk ,
30128 communityMintMaxVoteWeightSource ,
31129 minCommunityTokensToCreateGovernance ,
32130 undefined
33131 )
34132
133+ // If the current wallet is in the team then deposit the council token
134+ if ( councilMintPk )
135+ if ( walletAtaPk ) {
136+ await withDepositGoverningTokens (
137+ realmInstructions ,
138+ programId ,
139+ realmAddress ,
140+ walletAtaPk ,
141+ councilMintPk ,
142+ walletPubkey ,
143+ walletPubkey ,
144+ walletPubkey
145+ )
146+ } else {
147+ // Let's throw for now if the current wallet isn't in the team
148+ // TODO: To fix it we would have to make it temp. as part of the team and then remove after the realm is created
149+ throw new Error ( 'Current wallet must be in the team' )
150+ }
151+
35152 const transaction = new Transaction ( )
36- transaction . add ( ...instructions )
153+ transaction . add ( ...realmInstructions )
154+
155+ if ( ! wallet ) throw WalletConnectionError
156+
157+ if ( councilMembersChunks . length ) {
158+ await sendTransactions (
159+ connection ,
160+ wallet ,
161+ [ ...councilMembersChunks , realmInstructions ] ,
162+ [ ...councilSignersChunks , [ ] ] ,
163+ SequenceType . Sequential
164+ )
165+ } else {
166+ await sendTransaction ( { transaction, wallet, connection } )
167+ }
37168
38- await sendTransaction ( { transaction, wallet, connection } )
39169 return realmAddress
40170}
0 commit comments