@@ -13,13 +13,15 @@ import {
1313 Session ,
1414 SessionRequest ,
1515 SignedTransaction ,
16- Chain ,
1716} from 'ckb-walletconnect-wallet-sdk'
1817import WalletConnectSubject from '../models/subjects/wallet-connect-subject'
1918import { CurrentWalletSubject } from '../models/subjects/wallets'
2019import { CurrentNetworkIDSubject } from '../models/subjects/networks'
2120import { AccountExtendedPublicKey } from '../models/keys/key'
21+ import { Address as AddressInterface } from '../models/address'
2222import { AddressType } from '../models/keys/address'
23+ import TxDbChangedSubject from '../models/subjects/tx-db-changed-subject'
24+ import AddressDbChangedSubject from '../models/subjects/address-db-changed-subject'
2325import logger from '../utils/logger'
2426import { ResponseCode } from '../utils/const'
2527import WalletsService from '../services/wallets'
@@ -28,25 +30,57 @@ import AddressService from '../services/addresses'
2830
2931class Adapter implements CKBWalletAdapter {
3032 private walletID : string = ''
33+ private extendedKey : AccountExtendedPublicKey
3134
32- constructor ( props : { walletID : string } ) {
35+ constructor ( props : { walletID : string ; extendedKey : string } ) {
3336 this . walletID = props . walletID
37+ this . extendedKey = AccountExtendedPublicKey . parse ( props . extendedKey )
3438 }
3539
3640 public async ckb_getAddresses ( params : GetAddressesParams ) : Promise < {
3741 [ scriptBase : string ] : Address [ ]
3842 } > {
3943 const scriptBaseList = Object . keys ( params )
4044 if ( scriptBaseList . length ) {
41- const addresses = ( await AddressService . getAddressesByWalletId ( this . walletID ) )
42- . filter ( item => item . addressType === AddressType . Receiving )
43- . map ( ( { address, blake160 : identifier , balance, description = '' , addressIndex : index = '' } ) => ( {
45+ const { page, type } = params [ scriptBaseList [ 0 ] ]
46+ const { size = 10 , before, after } = page
47+ let resList = [ ] as AddressInterface [ ]
48+ if ( type === 'generate' ) {
49+ resList =
50+ ( await AddressService . generateAndSaveForExtendedKey ( {
51+ walletId : this . walletID ,
52+ extendedKey : this . extendedKey ,
53+ receivingAddressCount : size ,
54+ } ) ) || [ ]
55+ } else {
56+ const list = ( await AddressService . getAddressesWithBalancesByWalletId ( this . walletID ) ) . filter (
57+ item => item . addressType === AddressType . Receiving
58+ )
59+
60+ if ( before ) {
61+ const beforeItem = list . find ( item => item . address === before )
62+ if ( beforeItem ) {
63+ resList = list . filter ( item => item . addressIndex < beforeItem . addressIndex ) . slice ( - size )
64+ }
65+ } else if ( after ) {
66+ const afterItem = list . find ( item => item . address === after )
67+ if ( afterItem ) {
68+ resList = list . filter ( item => item . addressIndex > afterItem . addressIndex ) . slice ( size )
69+ }
70+ } else {
71+ resList = list . slice ( 0 , size )
72+ }
73+ }
74+
75+ const addresses = resList . map (
76+ ( { address, blake160 : identifier , balance, description = '' , addressIndex : index = '' } ) => ( {
4477 address,
4578 identifier,
4679 description,
4780 balance : balance ! ,
4881 index,
49- } ) )
82+ } )
83+ )
5084 return Promise . resolve ( {
5185 [ scriptBaseList [ 0 ] ] : addresses ,
5286 } )
@@ -81,33 +115,45 @@ export default class WalletConnectController {
81115 private sessions : Session [ ] = [ ]
82116 private requests : SessionRequest [ ] = [ ]
83117
84- private identity : string = ''
85- private chain : Chain = 'devnet'
118+ private addresses : AddressInterface [ ] = [ ]
86119
87- private async init ( ) {
120+ private getWallet ( ) {
88121 const currentWallet = WalletsService . getInstance ( ) . getCurrent ( )
89- const network = NetworksService . getInstance ( ) . getCurrent ( )
122+ if ( currentWallet ) {
123+ const { extendedKey, id } = currentWallet . toJSON ( )
124+ const identity = AccountExtendedPublicKey . parse ( extendedKey ) . addressPublicKey ( AddressType . Receiving , 0 )
90125
91- if ( ! currentWallet ) {
92- return
126+ return {
127+ identity,
128+ id,
129+ extendedKey,
130+ }
93131 }
132+ return {
133+ identity : '' ,
134+ }
135+ }
94136
95- const { extendedKey, id } = currentWallet . toJSON ( )
96- this . identity = AccountExtendedPublicKey . parse ( extendedKey ) . addressPublicKey ( AddressType . Receiving , 0 )
97-
137+ private getNetwork ( ) {
138+ const network = NetworksService . getInstance ( ) . getCurrent ( )
98139 switch ( network ?. chain ) {
99140 case 'ckb' :
100- this . chain = 'mainnet'
101- break
141+ return 'mainnet'
102142 case 'ckb_testnet' :
103- this . chain = 'testnet'
104- break
143+ case 'light_client_testnet' :
144+ return 'testnet'
105145 case 'ckb_dev' :
106- this . chain = 'devnet'
107- break
146+ return 'devnet'
108147 default :
109- this . chain = 'devnet'
110- break
148+ return 'devnet'
149+ }
150+ }
151+
152+ private async init ( ) {
153+ const wallet = this . getWallet ( )
154+
155+ if ( ! wallet . id ) {
156+ return
111157 }
112158
113159 const core = new Core ( {
@@ -124,7 +170,8 @@ export default class WalletConnectController {
124170 description : 'Neuron Wallet is a CKB wallet produced by Nervos Foundation. ' ,
125171 } ,
126172 adapter : new Adapter ( {
127- walletID : id ,
173+ walletID : wallet . id ,
174+ extendedKey : wallet . extendedKey ,
128175 } ) ,
129176 } )
130177
@@ -143,23 +190,89 @@ export default class WalletConnectController {
143190 } )
144191 }
145192
193+ private async updateAddresses ( emitEvent : boolean = true ) {
194+ const { id } = this . getWallet ( )
195+ if ( id ) {
196+ const list = await AddressService . getAddressesWithBalancesByWalletId ( id )
197+ const receriveList = list . filter ( item => item . addressType === AddressType . Receiving )
198+
199+ if ( ! this . addresses . length ) {
200+ this . addresses = receriveList
201+ return
202+ }
203+
204+ if ( receriveList . length > this . addresses . length ) {
205+ const addresses = receriveList
206+ . slice ( this . addresses . length )
207+ . map ( ( { address, blake160 : identifier , balance, description = '' , addressIndex : index = '' } ) => ( {
208+ address,
209+ identifier,
210+ description,
211+ balance : balance ! ,
212+ index,
213+ } ) )
214+ if ( emitEvent ) {
215+ WalletConnectController . client ?. changeAddresses ( {
216+ addresses,
217+ changeType : 'add' ,
218+ } )
219+ }
220+ } else if ( receriveList . length === this . addresses . length ) {
221+ const addresses = [ ] as Address [ ]
222+ receriveList . forEach ( ( item , index ) => {
223+ if ( item . txCount && ( this . addresses [ index ] ?. txCount || 0 ) < item . txCount )
224+ addresses . push ( {
225+ address : item . address ,
226+ identifier : item . blake160 ,
227+ description : item . description || '' ,
228+ balance : item . balance ! ,
229+ index,
230+ } )
231+ } )
232+ if ( emitEvent ) {
233+ WalletConnectController . client ?. changeAddresses ( {
234+ addresses,
235+ changeType : 'consume' ,
236+ } )
237+ }
238+ }
239+ this . addresses = receriveList
240+ }
241+ }
242+
146243 constructor ( ) {
147244 this . init ( )
148245
149246 CurrentWalletSubject . pipe ( debounceTime ( 50 ) ) . subscribe ( async params => {
150247 if ( params . currentWallet && WalletConnectController . client ) {
151- WalletConnectController . client . disconnectAllSessions ( )
152- this . init ( )
248+ const { identity, id, extendedKey } = this . getWallet ( )
249+ if ( id ) {
250+ WalletConnectController . client . updateAdapter ( new Adapter ( { walletID : id , extendedKey } ) )
251+ WalletConnectController . client . changeAccount ( identity )
252+ this . updateAddresses ( false )
253+ this . notify ( )
254+ }
153255 }
154256 } )
155257
156- CurrentNetworkIDSubject . subscribe ( async ( { currentNetworkID } ) => {
157- const currentNetwork = NetworksService . getInstance ( ) . get ( currentNetworkID )
158- if ( currentNetwork && WalletConnectController . client ) {
258+ CurrentNetworkIDSubject . subscribe ( ( ) => {
259+ if ( WalletConnectController . client ) {
159260 WalletConnectController . client . disconnectAllSessions ( )
160261 this . init ( )
161262 }
162263 } )
264+
265+ TxDbChangedSubject . getSubject ( )
266+ . pipe ( debounceTime ( 500 ) )
267+ . subscribe ( async ( ) => {
268+ this . updateAddresses ( )
269+ } )
270+
271+ AddressDbChangedSubject . getSubject ( )
272+ . pipe ( debounceTime ( 200 ) )
273+ . subscribe ( async ( ) => {
274+ this . updateAddresses ( )
275+ } )
163276 }
164277
165278 public async connect ( uri : string ) {
@@ -183,10 +296,11 @@ export default class WalletConnectController {
183296 public async approveSession ( params : { id : number ; scriptBases : string [ ] } ) {
184297 await WalletConnectController . client ?. approve ( {
185298 id : params . id ,
186- chain : this . chain ,
187- identity : this . identity ,
299+ network : this . getNetwork ( ) ,
300+ identity : this . getWallet ( ) . identity ,
188301 scriptBases : params . scriptBases ,
189302 } as ApproveParams )
303+ this . updateAddresses ( false )
190304 return {
191305 status : ResponseCode . Success ,
192306 }
@@ -218,7 +332,7 @@ export default class WalletConnectController {
218332 proposals : this . proposals ,
219333 sessions : this . sessions ,
220334 requests : this . requests ,
221- identity : this . identity ,
335+ identity : this . getWallet ( ) . identity ,
222336 } )
223337 }
224338}
0 commit comments