@bifold/core 2.4.4 → 2.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/commonjs/index.js +29 -0
  2. package/lib/commonjs/index.js.map +1 -1
  3. package/lib/commonjs/screens/ContactDetails.js +1 -1
  4. package/lib/commonjs/screens/ContactDetails.js.map +1 -1
  5. package/lib/commonjs/screens/CredentialDetails.js +1 -1
  6. package/lib/commonjs/screens/CredentialDetails.js.map +1 -1
  7. package/lib/commonjs/screens/JSONDetails.js +6 -3
  8. package/lib/commonjs/screens/JSONDetails.js.map +1 -1
  9. package/lib/commonjs/utils/ledger.js +145 -0
  10. package/lib/commonjs/utils/ledger.js.map +1 -0
  11. package/lib/module/index.js +1 -0
  12. package/lib/module/index.js.map +1 -1
  13. package/lib/module/screens/ContactDetails.js +1 -1
  14. package/lib/module/screens/ContactDetails.js.map +1 -1
  15. package/lib/module/screens/CredentialDetails.js +1 -1
  16. package/lib/module/screens/CredentialDetails.js.map +1 -1
  17. package/lib/module/screens/JSONDetails.js +6 -3
  18. package/lib/module/screens/JSONDetails.js.map +1 -1
  19. package/lib/module/utils/ledger.js +137 -0
  20. package/lib/module/utils/ledger.js.map +1 -0
  21. package/lib/typescript/src/index.d.ts +2 -0
  22. package/lib/typescript/src/index.d.ts.map +1 -1
  23. package/lib/typescript/src/screens/JSONDetails.d.ts.map +1 -1
  24. package/lib/typescript/src/types/navigators.d.ts +1 -1
  25. package/lib/typescript/src/types/navigators.d.ts.map +1 -1
  26. package/lib/typescript/src/utils/ledger.d.ts +101 -0
  27. package/lib/typescript/src/utils/ledger.d.ts.map +1 -0
  28. package/package.json +3 -3
  29. package/src/index.ts +2 -0
  30. package/src/screens/ContactDetails.tsx +1 -1
  31. package/src/screens/CredentialDetails.tsx +1 -1
  32. package/src/screens/JSONDetails.tsx +3 -1
  33. package/src/types/navigators.ts +1 -1
  34. package/src/utils/ledger.ts +212 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bifold/core",
3
- "version": "2.4.4",
3
+ "version": "2.4.6",
4
4
  "main": "lib/commonjs/index.js",
5
5
  "module": "lib/module/index.js",
6
6
  "react-native": "src/index.ts",
@@ -33,8 +33,8 @@
33
33
  "devDependencies": {
34
34
  "@babel/core": "~7.22.20",
35
35
  "@babel/runtime": "~7.23.9",
36
- "@bifold/oca": "2.4.4",
37
- "@bifold/verifier": "2.4.4",
36
+ "@bifold/oca": "2.4.6",
37
+ "@bifold/verifier": "2.4.6",
38
38
  "@commitlint/cli": "~11.0.0",
39
39
  "@credo-ts/anoncreds": "0.5.13",
40
40
  "@credo-ts/askar": "0.5.13",
package/src/index.ts CHANGED
@@ -103,7 +103,9 @@ export {
103
103
  } from './utils/helpers'
104
104
  export { isValidAnonCredsCredential, getCredentialIdentifiers } from './utils/credential'
105
105
  export { buildFieldsFromAnonCredsCredential } from './utils/oca'
106
+ export { IndyLedger, getIndyLedgers, readIndyLedgersFromFile, writeIndyLedgersToFile } from './utils/ledger'
106
107
 
108
+ export type { IndyLedgerConfig, IndyLedgerJSON, IndyLedgersRecord, IndyLedgerFileSystem } from './utils/ledger'
107
109
  export type { AnimatedComponents } from './animated-components'
108
110
  export type {
109
111
  ISVGAssets,
@@ -217,7 +217,7 @@ const ContactDetails: React.FC<ContactDetailsProps> = ({ route }) => {
217
217
  }, [navigation, connectionId])
218
218
 
219
219
  const callViewJSONDetails = useCallback(() => {
220
- navigation.navigate(Screens.JSONDetails, { jsonBlob: JSON.stringify(connection, null, 2) })
220
+ navigation.navigate(Screens.JSONDetails, { jsonBlob: connection })
221
221
  }, [navigation, connection])
222
222
 
223
223
  const contactLabel = useMemo(
@@ -136,7 +136,7 @@ const CredentialDetails: React.FC<CredentialDetailsProps> = ({ navigation, route
136
136
  const callViewJSONDetails = useCallback(() => {
137
137
  navigation.navigate(Stacks.ContactStack, {
138
138
  screen: Screens.JSONDetails,
139
- params: { jsonBlob: JSON.stringify(credential, null, 2) },
139
+ params: { jsonBlob: credential },
140
140
  })
141
141
  }, [navigation, credential])
142
142
 
@@ -11,6 +11,7 @@ import { ScrollView } from 'react-native-gesture-handler'
11
11
  import Clipboard from '@react-native-clipboard/clipboard'
12
12
  import Toast from 'react-native-toast-message'
13
13
  import { ToastType } from '../components/toast/BaseToast'
14
+ import { useNetInfo } from '@react-native-community/netinfo'
14
15
 
15
16
  type JSONDetailsProps = StackScreenProps<ContactStackParams, Screens.JSONDetails>
16
17
 
@@ -20,7 +21,8 @@ const JSONDetails = ({ route }: JSONDetailsProps) => {
20
21
  }
21
22
  const { t } = useTranslation()
22
23
  const { ColorPalette } = useTheme()
23
- const { jsonBlob } = route.params
24
+ const netInfo = useNetInfo()
25
+ const jsonBlob = JSON.stringify({ caller_info: route.params.jsonBlob, network_info: netInfo }, null, 2)
24
26
  const styles = StyleSheet.create({
25
27
  container: {
26
28
  flex: 1,
@@ -125,7 +125,7 @@ export type ContactStackParams = {
125
125
  [Screens.CredentialOffer]: { credentialId: string }
126
126
  [Screens.ProofDetails]: { recordId: string; isHistory?: boolean }
127
127
  [Screens.ProofRequest]: { proofId: string }
128
- [Screens.JSONDetails]: { jsonBlob: string }
128
+ [Screens.JSONDetails]: { jsonBlob: any }
129
129
  }
130
130
 
131
131
  export type ProofRequestsStackParams = {
@@ -0,0 +1,212 @@
1
+ import { IndyVdrPoolConfig } from '@credo-ts/indy-vdr'
2
+ import axios from 'axios'
3
+
4
+ const INDY_NETWORK_URL =
5
+ 'https://raw.githubusercontent.com/hyperledger/indy-node-monitor/main/fetch-validator-status/networks.json'
6
+
7
+ const ERROR_TAG = 'LEDGER ERROR'
8
+
9
+ export enum IndyLedger {
10
+ SOVRIN_BUILDER_NET = 'sbn',
11
+ SOVRIN_STAGING_NET = 'ssn',
12
+ SOVERIN_MAIN_NET = 'smn',
13
+ LOCAL_VON_NETWORK = 'vn',
14
+ LINUX_LOCAL_VON_NETWORK = 'lln',
15
+ BCOVRIN_DEV = 'bcd',
16
+ BCOVRIN_TEST = 'bct',
17
+ BCOVRIN = 'bcp',
18
+ GREENLIGHT_DEV_LEDGER = 'gld',
19
+ INDICO_MAINNET = 'imn',
20
+ INDICO_DEMONET = 'idn',
21
+ INDICO_TESTNET = 'itn',
22
+ CANDY_DEV_NETWORK = 'cdn',
23
+ CANDY_TEST_NETWORK = 'ctn',
24
+ CANDY_PRODUCTION_NETWORK = 'cpn',
25
+ }
26
+
27
+ export interface IndyLedgerConfig {
28
+ ledgerId: IndyLedger
29
+ isProduction: boolean
30
+ doNotConnectOnStartup?: true
31
+ }
32
+
33
+ export interface IndyLedgerJSON extends IndyVdrPoolConfig {
34
+ // A human-readable identifier for the ledger, useful for identifing the ledger in the JSON file.
35
+ // Note: This value will not be used downstream as the IndyVdrPoolConfig interface will exclude it.
36
+ id: string
37
+ }
38
+
39
+ export type IndyLedgersRecord = Record<
40
+ IndyLedger,
41
+ {
42
+ name: string
43
+ indyNamespace: string
44
+ genesisUrl: string
45
+ }
46
+ >
47
+
48
+ // This interface allows us to abstract the file system operations,
49
+ // preventing android from complaining about the use of the Node.js module 'fs'.
50
+ export interface IndyLedgerFileSystem {
51
+ /**
52
+ * Writes data to a file at the specified file path.
53
+ *
54
+ * @param {string} filePath - The path to the file where data should be written.
55
+ * @param {*} {string} data - The data to write to the file.
56
+ * @returns {*} {void}
57
+ */
58
+ writeFile: (filePath: string, data: string) => void
59
+ /**
60
+ * Reads and returns the content of a file at the specified file path.
61
+ *
62
+ * @param {string} filePath - The path to the file to read.
63
+ * @returns {*} {string} - The content of the file as a string.
64
+ */
65
+ readFile: (filePath: string) => string
66
+ /**
67
+ * Checks if a file exists at the specified file path.
68
+ *
69
+ * @param {string} filePath - The path to the file to check.
70
+ * @returns {*} {boolean} - True if the file exists, false otherwise.
71
+ */
72
+ fileExists: (filePath: string) => boolean
73
+ /**
74
+ * Resolves and returns the absolute path for a given file path.
75
+ *
76
+ * @example ./ledgers.json -> /Users/username/project/ledgers.json
77
+ *
78
+ * @param {string} filePath - The file path to resolve.
79
+ * @returns {*} {string} - The resolved absolute file path.
80
+ */
81
+ pathResolve: (filePath: string) => string
82
+ }
83
+
84
+ /**
85
+ * Fetches the content from a given URL and returns it as a Promise.
86
+ *
87
+ * @throws {Error} - Throws an error if the fetch operation fails.
88
+ * @template T - The type of content expected from the URL.
89
+ * @param {string} url - The URL to fetch content from.
90
+ * @returns {*} {Promise<T>} - A promise that resolves to the content fetched from the URL
91
+ */
92
+ export async function _fetchUrlContent<T>(url: string): Promise<T> {
93
+ try {
94
+ const response = await axios.get<T>(url)
95
+ return response.data
96
+ } catch (error: any) {
97
+ throw new Error(`${ERROR_TAG}: Failed to fetch content from URL ${url}: ${error.message}`)
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Fetches and returns a list of Indy ledgers based on the provided configurations.
103
+ *
104
+ * @throws {Error} - Throws an error if a ledgerConfig is not found in the IndyLedgersRecord.
105
+ * @param {IndyLedgerConfig[]} indyLedgerConfigs - The list of supported Indy ledger configurations.
106
+ * @returns {*} {Promise<IndyLedgerJSON[]>} - A promise that resolves to an array of ledgers.
107
+ */
108
+ export async function getIndyLedgers(indyLedgerConfigs: IndyLedgerConfig[]): Promise<IndyLedgerJSON[]> {
109
+ if (!indyLedgerConfigs.length) {
110
+ return []
111
+ }
112
+
113
+ const allIndyLedgers = await _fetchUrlContent<IndyLedgersRecord>(INDY_NETWORK_URL)
114
+
115
+ const ledgers: IndyLedgerJSON[] = []
116
+ // Iterate through the supported network configs and map them to the Indy ledgers
117
+ for (const ledgerConfig of indyLedgerConfigs) {
118
+ const indyLedger = allIndyLedgers[ledgerConfig.ledgerId]
119
+
120
+ if (!indyLedger) {
121
+ throw new Error(`${ERROR_TAG}: Ledger config for ${ledgerConfig.ledgerId} not found`)
122
+ }
123
+
124
+ const ledgerId = indyLedger.name
125
+ .split(' ')
126
+ .filter((word) => !/\W+/im.test(word))
127
+ .join('')
128
+
129
+ ledgers.push({
130
+ id: ledgerId,
131
+ indyNamespace: indyLedger.indyNamespace,
132
+ isProduction: ledgerConfig.isProduction,
133
+ connectOnStartup: !ledgerConfig.doNotConnectOnStartup,
134
+ // This url will need to be fetched to get the genesis transactions
135
+ genesisTransactions: indyLedger.genesisUrl,
136
+ })
137
+ }
138
+
139
+ // Step 1: Collect all genesis transaction promises
140
+ const genesisPromises = ledgers.map((ledger) => _fetchUrlContent<string>(ledger.genesisTransactions))
141
+
142
+ // Step 2: Await all promises to resolve in parallel
143
+ const genesisTransactions = await Promise.all(genesisPromises)
144
+
145
+ // Step 3: Assign the fetched genesis transactions back to the ledgers
146
+ genesisTransactions.forEach((transactions, index) => {
147
+ ledgers[index].genesisTransactions = transactions.trim()
148
+ })
149
+
150
+ return ledgers
151
+ }
152
+
153
+ /**
154
+ * Writes the provided Indy ledgers to a JSON file at the specified file path.
155
+ *
156
+ * @throws {Error} - Throws an error if writing to the file fails or if the file path is invalid.
157
+ * @param {IndyLedgerFileSystem} fileSystem - The file system interface to use for writing the file.
158
+ * @param {string} filePath - The path to the JSON file where the ledgers should be written.
159
+ * @param {IndyLedgerJSON[]} ledgers - The array of Indy ledgers to write to the file.
160
+ * @returns {*} {void}
161
+ */
162
+ export function writeIndyLedgersToFile(
163
+ fileSystem: IndyLedgerFileSystem,
164
+ filePath: string,
165
+ ledgers: IndyLedgerJSON[]
166
+ ): void {
167
+ try {
168
+ if (!filePath.endsWith('.json')) {
169
+ throw new Error('File path must point to a JSON file')
170
+ }
171
+
172
+ // Skip writing to file if the new ledgers are the same
173
+ if (
174
+ fileSystem.fileExists(filePath) &&
175
+ JSON.stringify(readIndyLedgersFromFile(fileSystem, filePath)) === JSON.stringify(ledgers)
176
+ ) {
177
+ return
178
+ }
179
+
180
+ const jsonContent = JSON.stringify(ledgers, null, 2)
181
+
182
+ // Convert to absolute path ie: ./ledgers.json -> /Users/username/project/ledgers.json
183
+ const absoluteFilePath = fileSystem.pathResolve(filePath)
184
+ fileSystem.writeFile(absoluteFilePath, jsonContent)
185
+ } catch (error: any) {
186
+ throw new Error(`${ERROR_TAG}: Failed to write ledgers to file ${filePath}: ${error.message}`)
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Reads and parses Indy ledgers from a JSON file at the specified file path.
192
+ *
193
+ * @throws {Error} - Throws an error if reading from the file fails, if the file path is invalid, or if parsing fails.
194
+ * @param {IndyLedgerFileSystem} fileSystem - The file system interface to use for reading the file.
195
+ * @param {string} filePath - The path to the JSON file to read the ledgers from.
196
+ * @returns {*} {IndyLedgerJSON[]} - An array of Indy ledgers read from the file.
197
+ */
198
+ export function readIndyLedgersFromFile(fileSystem: IndyLedgerFileSystem, filePath: string): IndyLedgerJSON[] {
199
+ try {
200
+ if (!filePath.endsWith('.json')) {
201
+ throw new Error('File path must point to a JSON file')
202
+ }
203
+
204
+ // Convert to absolute path ie: ./ledgers.json -> /Users/username/project/ledgers.json
205
+ const absoluteFilePath = fileSystem.pathResolve(filePath)
206
+ const jsonContent = fileSystem.readFile(absoluteFilePath)
207
+
208
+ return JSON.parse(jsonContent)
209
+ } catch (error: any) {
210
+ throw new Error(`${ERROR_TAG}: Failed to read ledgers from file ${filePath}: ${error.message}`)
211
+ }
212
+ }