11import {
2+ Account ,
23 Address ,
34 assertAccountExists ,
5+ assertAccountsExist ,
46 fetchEncodedAccount ,
7+ fetchEncodedAccounts ,
58 GetAccountInfoApi ,
69 getBase16Decoder ,
710 getBase16Encoder ,
811 getBase58Decoder ,
912 getBase58Encoder ,
1013 getBase64Decoder ,
1114 getBase64Encoder ,
15+ GetMultipleAccountsApi ,
1216 getUtf8Decoder ,
1317 getUtf8Encoder ,
1418 pipe ,
@@ -23,6 +27,7 @@ import {
2327 Encoding ,
2428 getExternalDataDecoder ,
2529 getExternalDataEncoder ,
30+ Metadata ,
2631} from './generated' ;
2732
2833export type PackedData = {
@@ -32,6 +37,12 @@ export type PackedData = {
3237 data : ReadonlyUint8Array ;
3338} ;
3439
40+ export type UnpackedData = {
41+ address : Address ;
42+ offset ?: number ;
43+ length ?: number ;
44+ } ;
45+
3546export function packDirectData ( input : {
3647 content : string ;
3748 /** Defaults to `Compression.Zlib`. */
@@ -120,11 +131,7 @@ export async function unpackAndFetchUrlData(
120131 return await response . text ( ) ;
121132}
122133
123- export function unpackExternalData ( data : ReadonlyUint8Array ) : {
124- address : Address ;
125- offset ?: number ;
126- length ?: number ;
127- } {
134+ export function unpackExternalData ( data : ReadonlyUint8Array ) : UnpackedData {
128135 const externalData = getExternalDataDecoder ( ) . decode ( data ) ;
129136 return {
130137 address : externalData . address ,
@@ -133,27 +140,47 @@ export function unpackExternalData(data: ReadonlyUint8Array): {
133140 } ;
134141}
135142
136- export async function unpackAndFetchExternalData (
137- input : Omit < PackedData , 'dataSource' > & { rpc : Rpc < GetAccountInfoApi > }
138- ) : Promise < string > {
139- const externalData = unpackExternalData ( input . data ) ;
140- const account = await fetchEncodedAccount ( input . rpc , externalData . address ) ;
141- assertAccountExists ( account ) ;
143+ export function uncompressAndDecodeExternalData ( {
144+ compression,
145+ encoding,
146+ account,
147+ unpackedExternalData,
148+ } : Pick < PackedData , 'compression' | 'encoding' > & {
149+ account : Account < Uint8Array > ;
150+ unpackedExternalData : UnpackedData ;
151+ } ) : string {
142152 let data = account . data ;
143- if ( externalData . offset !== undefined ) {
144- data = data . slice ( externalData . offset ) ;
153+ if ( unpackedExternalData . offset !== undefined ) {
154+ data = data . slice ( unpackedExternalData . offset ) ;
145155 }
146- if ( externalData . length !== undefined ) {
147- data = data . slice ( 0 , externalData . length ) ;
156+ if ( unpackedExternalData . length !== undefined ) {
157+ data = data . slice ( 0 , unpackedExternalData . length ) ;
148158 }
149159 if ( data . length === 0 ) {
150160 return '' ;
151161 }
152162 return pipe (
153163 data ,
154- ( d ) => uncompressData ( d , input . compression ) ,
155- ( d ) => decodeData ( d , input . encoding )
164+ ( d ) => uncompressData ( d , compression ) ,
165+ ( d ) => decodeData ( d , encoding )
166+ ) ;
167+ }
168+
169+ export async function unpackAndFetchExternalData (
170+ input : Omit < PackedData , 'dataSource' > & { rpc : Rpc < GetAccountInfoApi > }
171+ ) : Promise < string > {
172+ const unpackedExternalData = unpackExternalData ( input . data ) ;
173+ const account = await fetchEncodedAccount (
174+ input . rpc ,
175+ unpackedExternalData . address
156176 ) ;
177+ assertAccountExists ( account ) ;
178+ return uncompressAndDecodeExternalData ( {
179+ compression : input . compression ,
180+ encoding : input . encoding ,
181+ account,
182+ unpackedExternalData,
183+ } ) ;
157184}
158185
159186export async function unpackAndFetchData (
@@ -171,6 +198,50 @@ export async function unpackAndFetchData(
171198 }
172199}
173200
201+ export async function unpackAndFetchAllData ( {
202+ accounts,
203+ rpc,
204+ } : {
205+ accounts : Account < Metadata > [ ] ;
206+ rpc : Rpc < GetMultipleAccountsApi > ;
207+ } ) {
208+ const unpackedExternalAccounts = accounts
209+ . filter ( ( account ) => account . data . dataSource === DataSource . External )
210+ . map ( ( account ) => ( {
211+ address : account . address ,
212+ unpacked : unpackExternalData ( account . data . data ) ,
213+ } ) ) ;
214+
215+ const fetchedExternalAccounts = await fetchEncodedAccounts (
216+ rpc ,
217+ unpackedExternalAccounts . map ( ( account ) => account . unpacked . address )
218+ ) ;
219+ assertAccountsExist ( fetchedExternalAccounts ) ;
220+
221+ return Promise . all (
222+ accounts . map ( async ( account ) => {
223+ switch ( account . data . dataSource ) {
224+ case DataSource . Direct :
225+ return unpackDirectData ( account . data ) ;
226+ case DataSource . Url :
227+ return await unpackAndFetchUrlData ( account . data ) ;
228+ case DataSource . External : {
229+ const accountIndex = unpackedExternalAccounts . findIndex (
230+ ( acc ) => acc . address === account . address
231+ ) ;
232+ return uncompressAndDecodeExternalData ( {
233+ compression : account . data . compression ,
234+ encoding : account . data . encoding ,
235+ account : fetchedExternalAccounts [ accountIndex ] ,
236+ unpackedExternalData :
237+ unpackedExternalAccounts [ accountIndex ] . unpacked ,
238+ } ) ;
239+ }
240+ }
241+ } )
242+ ) ;
243+ }
244+
174245export function compressData (
175246 data : ReadonlyUint8Array ,
176247 compression : Compression
0 commit comments