emblem-vault-sdk 2.3.6 → 3.0.0-experimental

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 (147) hide show
  1. package/.traces/blockchain-provider-abstraction-plan.md +302 -0
  2. package/.traces/notes.md +43 -0
  3. package/.traces/readme-verification-trace.md +988 -0
  4. package/.traces/test-migration-status.md +227 -0
  5. package/.traces/tests-consolidated-trace.md +667 -0
  6. package/dist/abi/abi.json +53 -0
  7. package/dist/bundle.js +21602 -17419
  8. package/dist/clients/emblemVaultSolanaWalletClient.d.ts +74 -0
  9. package/dist/clients/emblemVaultSolanaWalletClient.js +149 -0
  10. package/dist/clients/emblemVaultSolanaWalletClient.js.map +1 -0
  11. package/dist/clients/emblemVaultWalletClient.d.ts +52 -0
  12. package/dist/clients/emblemVaultWalletClient.js +110 -0
  13. package/dist/clients/emblemVaultWalletClient.js.map +1 -0
  14. package/dist/derive.js +7 -0
  15. package/dist/derive.js.map +1 -0
  16. package/dist/index.js +319 -114
  17. package/dist/index.js.map +1 -0
  18. package/dist/providers/ProviderManager.d.ts +57 -0
  19. package/dist/providers/ProviderManager.js +283 -0
  20. package/dist/providers/ProviderManager.js.map +1 -0
  21. package/dist/providers.d.ts +101 -0
  22. package/dist/providers.js +96 -0
  23. package/dist/providers.js.map +1 -0
  24. package/dist/types.js +1 -0
  25. package/dist/types.js.map +1 -0
  26. package/dist/utils.js +61 -58
  27. package/dist/utils.js.map +1 -0
  28. package/docs/bundle.js +21602 -17419
  29. package/docs/index.html +150 -13
  30. package/docs/local.html +385 -0
  31. package/docs/steps.html +420 -53
  32. package/package.json +22 -13
  33. package/readme.md +795 -21
  34. package/src/abi/abi.json +54 -1
  35. package/src/clients/emblemVaultSolanaWalletClient.ts +257 -0
  36. package/src/clients/emblemVaultWalletClient.ts +159 -0
  37. package/src/derive.ts +5 -5
  38. package/src/index.ts +320 -102
  39. package/src/providers/ProviderManager.ts +254 -0
  40. package/src/providers.ts +163 -0
  41. package/src/types.ts +50 -0
  42. package/src/utils.ts +63 -62
  43. package/test/.mocharc.js +8 -0
  44. package/test/README.md +212 -0
  45. package/test/fixtures/ethscriptions/balance-with-native-first.json +24 -0
  46. package/test/fixtures/ethscriptions/balance-with-native.json +23 -0
  47. package/test/fixtures/ethscriptions/balance.json +18 -0
  48. package/test/helpers/sdkLoader.js +88 -0
  49. package/test/helpers/setup.js +55 -0
  50. package/test/integration/ApiOperations.spec.js +102 -0
  51. package/test/integration/VaultAI.spec.js +57 -0
  52. package/test/integration/VaultCreation.spec.js +95 -0
  53. package/test/mocks.js +127 -0
  54. package/test/tsconfig.json +25 -0
  55. package/test/unit/AllowedBells.spec.js +53 -0
  56. package/test/unit/AllowedBitcoinDeGods.spec.js +53 -0
  57. package/test/unit/AllowedBitcoinOrdinals.spec.js +46 -0
  58. package/test/unit/AllowedCounterparty.spec.js +66 -0
  59. package/test/unit/AllowedCursedOrdinals.spec.js +68 -0
  60. package/test/unit/AllowedEmbells.spec.js +11 -0
  61. package/test/unit/AllowedEmbels.spec.js +11 -0
  62. package/test/unit/AllowedEmblemOpen.spec.js +20 -0
  63. package/test/unit/AllowedEthscriptions.spec.js +53 -0
  64. package/test/unit/AllowedHardcodedNfts.spec.js +77 -0
  65. package/test/unit/AllowedNamecoin.spec.js +33 -0
  66. package/test/unit/AllowedOrdi.spec.js +46 -0
  67. package/test/unit/AllowedOxbt.spec.js +46 -0
  68. package/test/unit/AllowedProjectCollection.spec.js +51 -0
  69. package/test/unit/AllowedProtocolCollection.spec.js +44 -0
  70. package/test/unit/AllowedStamps.spec.js +78 -0
  71. package/test/unit/DarkfarmsMetadata.spec.js +10 -0
  72. package/test/unit/EmblemVaultSdk.spec.js +188 -0
  73. package/test/unit/Providers.spec.js +290 -0
  74. package/test/unit/ResourceMonitor.spec.js +111 -0
  75. package/test/unit/SDKMemoryLeaks.spec.js +176 -0
  76. package/test/unit/Signing.spec.js +321 -0
  77. package/test/unit/VaultAI.spec.js +140 -0
  78. package/test/unit/clients/EmblemVaultSolanaWalletClient.spec.js +296 -0
  79. package/test/unit/clients/EmblemVaultWalletClient.spec.js +246 -0
  80. package/test/utils/ResourceMonitor.js +169 -0
  81. package/test/windsurf-rules.md +68 -0
  82. package/tsconfig.json +7 -3
  83. package/types/derive.d.ts +0 -5
  84. package/types/index.d.ts +152 -32
  85. package/types/types.d.ts +43 -0
  86. package/types/utils.d.ts +7 -1
  87. package/dist/abi/quote.js +0 -29
  88. package/dist/abi/quote.json +0 -26
  89. package/jest.config.js +0 -6
  90. package/tests/AllowedBells.test.ts +0 -53
  91. package/tests/AllowedBitcoinDeGods.test.ts +0 -53
  92. package/tests/AllowedBitcoinOrdinals.test.ts +0 -46
  93. package/tests/AllowedCounterparty.test.ts +0 -45
  94. package/tests/AllowedCursedOrdinals.test.ts +0 -68
  95. package/tests/AllowedEmbells.test.ts +0 -12
  96. package/tests/AllowedEmbels.test.ts +0 -16
  97. package/tests/AllowedEmblemOpen.test.ts +0 -20
  98. package/tests/AllowedEthscriptions.test.ts +0 -39
  99. package/tests/AllowedHardcodedNfts.test.ts +0 -78
  100. package/tests/AllowedNamecoin.test.ts +0 -33
  101. package/tests/AllowedOrdi.test.ts +0 -47
  102. package/tests/AllowedOxbt.test.ts +0 -47
  103. package/tests/AllowedProjectlCollection.test.ts +0 -51
  104. package/tests/AllowedProtocolCollection.test.ts +0 -44
  105. package/tests/AllowedStamps.test.ts +0 -73
  106. package/tests/DarkfarmsMetadata.test.ts +0 -10
  107. package/tests/EmblemVaultSdk.test.ts +0 -124
  108. package/tests/fixtures/embels/balance.json +0 -10
  109. package/tests/fixtures/ethscriptions/balance-with-native-first.json +0 -69
  110. package/tests/fixtures/ethscriptions/balance-with-native.json +0 -37
  111. package/tests/fixtures/ethscriptions/balance.json +0 -64
  112. /package/{tests → test}/fixtures/bells/balance-with-non-bell-first.json +0 -0
  113. /package/{tests → test}/fixtures/bells/balance-with-non-bell.json +0 -0
  114. /package/{tests → test}/fixtures/bells/balance.json +0 -0
  115. /package/{tests → test}/fixtures/bitcoin-degods/balance-with-non-degods-first.json +0 -0
  116. /package/{tests → test}/fixtures/bitcoin-degods/balance-with-non-degods.json +0 -0
  117. /package/{tests → test}/fixtures/bitcoin-degods/balance.json +0 -0
  118. /package/{tests → test}/fixtures/bitcoin-ordinals/balance-with-native-first.json +0 -0
  119. /package/{tests → test}/fixtures/bitcoin-ordinals/balance-with-only-native.json +0 -0
  120. /package/{tests → test}/fixtures/bitcoin-ordinals/balance.json +0 -0
  121. /package/{tests → test}/fixtures/counterparty/balance-with-multiple.json +0 -0
  122. /package/{tests → test}/fixtures/counterparty/balance.json +0 -0
  123. /package/{tests → test}/fixtures/cursed-ordinals/balance-with-native-first.json +0 -0
  124. /package/{tests → test}/fixtures/cursed-ordinals/balance-with-native.json +0 -0
  125. /package/{tests → test}/fixtures/cursed-ordinals/balance.json +0 -0
  126. /package/{tests → test}/fixtures/dogeparty/balance-with-non-dogeparty-first.json +0 -0
  127. /package/{tests → test}/fixtures/dogeparty/balance-with-non-dogeparty.json +0 -0
  128. /package/{tests → test}/fixtures/dogeparty/balance.json +0 -0
  129. /package/{tests → test}/fixtures/emblem-open/balance.json +0 -0
  130. /package/{tests → test}/fixtures/hardcoded-nfts/balance-witn-non-hardcoded-first.json +0 -0
  131. /package/{tests → test}/fixtures/hardcoded-nfts/balance-witn-non-hardcoded.json +0 -0
  132. /package/{tests → test}/fixtures/hardcoded-nfts/balance.json +0 -0
  133. /package/{tests → test}/fixtures/megapunks/balance-with-non-megapunk-first.json +0 -0
  134. /package/{tests → test}/fixtures/megapunks/balance-with-non-megapunk.json +0 -0
  135. /package/{tests → test}/fixtures/megapunks/balance.json +0 -0
  136. /package/{tests → test}/fixtures/namecoin/balance-with-native-first.json +0 -0
  137. /package/{tests → test}/fixtures/namecoin/balance-with-native.json +0 -0
  138. /package/{tests → test}/fixtures/namecoin/balance.json +0 -0
  139. /package/{tests → test}/fixtures/ordi/balance-with-native-first.json +0 -0
  140. /package/{tests → test}/fixtures/ordi/balance-with-native.json +0 -0
  141. /package/{tests → test}/fixtures/ordi/balance.json +0 -0
  142. /package/{tests → test}/fixtures/oxbt/balance-with-native-first.json +0 -0
  143. /package/{tests → test}/fixtures/oxbt/balance-with-native.json +0 -0
  144. /package/{tests → test}/fixtures/oxbt/balance.json +0 -0
  145. /package/{tests → test}/fixtures/stamps/balance-with-non-stamps-first.json +0 -0
  146. /package/{tests → test}/fixtures/stamps/balance-with-non-stamps.json +0 -0
  147. /package/{tests → test}/fixtures/stamps/balance.json +0 -0
package/src/index.ts CHANGED
@@ -1,68 +1,192 @@
1
1
  import { BigNumber } from '@ethersproject/bignumber'
2
- import { Collection, CuratedCollectionsResponse, MetaData, Ownership, Vault } from './types';
3
- import { COIN_TO_NETWORK, NFT_DATA, checkContentType, decryptKeys, evaluateFacts, fetchData, generateTemplate, genericGuard, getHandlerContract, getLegacyContract, getQuoteContractObject, getSatsConnectAddress, getTorusKeys, metadataAllProjects, metadataObj2Arr, pad, signPSBT, templateGuard } from './utils';
4
- import { getAddress, BitcoinNetworkType, AddressPurpose, signTransaction } from "sats-connect";
2
+ import { AiVaultInfo, Balance, Collection, CuratedCollectionsResponse, MetaData, Ownership, v3LocalMintSignature, Vault } from './types';
3
+ import { NFT_DATA, checkContentType, decryptKeys, fetchData, generateTemplate, genericGuard, getHandlerContract, getLegacyContract, getQuoteContractObject, getSatsConnectAddress, getTorusKeys, metadataAllProjects, metadataObj2Arr, signPSBT, templateGuard } from './utils';
5
4
  import { generateTaprootAddressFromMnemonic, getPsbtTxnSize } from './derive';
5
+ import { BlockchainProvider, BlockchainType, detectProviderType, EthereumProvider, Web3ProviderAdapter } from './providers';
6
+ import { ProviderManager } from './providers/ProviderManager';
7
+ import { createEmblemVaultWalletClient, EmblemVaultWalletClient, EmblemVaultWalletClientConfig } from './clients/emblemVaultWalletClient';
8
+ import { createEmblemVaultSolanaWalletClient, EmblemVaultSolanaWalletClient, EmblemVaultSolanaWalletClientConfig } from './clients/emblemVaultSolanaWalletClient';
9
+
6
10
  const SDK_VERSION = '__SDK_VERSION__';
7
11
 
8
- class EmblemVaultSDK {
12
+ export class EmblemVaultSDK {
9
13
  private baseUrl: string;
10
14
  private v3Url: string;
11
15
  private sigUrl: string;
12
- constructor(private apiKey: string, baseUrl?: string, v3Url?: string, sigUrl?: string) {
13
- console.log('EmblemVaultSDK version:', SDK_VERSION)
16
+ private aiUrl: string;
17
+ private aiApiKey?: string;
18
+ private byoKey?: string;
19
+ private providerManager: ProviderManager;
20
+ version: string;
21
+
22
+ constructor(private apiKey: string, baseUrl?: string, v3Url?: string, sigUrl?: string, aiUrl?: string, aiApiKey?: string, byoKey?: string) {
23
+ // console.log('EmblemVaultSDK version:', SDK_VERSION)
14
24
  if (!apiKey) {
15
25
  throw new Error('API key is required');
16
26
  }
17
27
  this.baseUrl = baseUrl || 'https://v2.emblemvault.io';
18
28
  this.v3Url = v3Url || 'https://v3.emblemvault.io';
19
29
  this.sigUrl = sigUrl || 'https://tor-us-signer-coval.vercel.app';
30
+ this.aiUrl = aiUrl || 'https://api.emblemvault.ai';
31
+ this.aiApiKey = aiApiKey || undefined;
32
+ this.byoKey = byoKey || undefined;
33
+ this.version = SDK_VERSION;
34
+ this.providerManager = new ProviderManager();
35
+ }
36
+
37
+ /**
38
+ * Register a blockchain provider for a specific blockchain type
39
+ * @param type The blockchain type
40
+ * @param provider The provider instance
41
+ */
42
+ registerProvider(type: BlockchainType, provider: any): void {
43
+ this.providerManager.registerProvider(type, provider);
44
+ }
45
+
46
+ /**
47
+ * Get a registered provider for a specific blockchain type
48
+ * @param type The blockchain type
49
+ * @returns The provider instance or undefined if not registered
50
+ */
51
+ getProvider(type: BlockchainType): any {
52
+ return this.providerManager.getProvider(type);
53
+ }
54
+
55
+ /**
56
+ * Check if a provider is registered for a specific blockchain type
57
+ * @param type The blockchain type
58
+ * @returns True if a provider is registered for the specified type
59
+ */
60
+ hasProvider(type: BlockchainType): boolean {
61
+ return this.providerManager.hasProvider(type);
62
+ }
63
+
64
+ /**
65
+ * Get or detect a provider for a specific blockchain type
66
+ * If a provider is registered, it will be returned
67
+ * Otherwise, it will try to detect a provider in the environment
68
+ * @param type The blockchain type
69
+ * @returns A promise that resolves to the provider instance
70
+ * @throws Error if no provider is available
71
+ */
72
+ async getOrDetectProvider(type: BlockchainType): Promise<any> {
73
+ return this.providerManager.getOrDetectProvider(type);
74
+ }
75
+
76
+ /**
77
+ * Creates a Wallet Client instance powered by the Emblem Vault TEE signer.
78
+ *
79
+ * @param config - Configuration specific to the wallet client, like the walletId.
80
+ * @returns An EmblemVaultWalletClient instance.
81
+ */
82
+ createWalletClient(config: Omit<EmblemVaultWalletClientConfig, 'sdk'>): EmblemVaultWalletClient {
83
+ if (!this.apiKey) {
84
+ throw new Error("SDK must be initialized with an API key before creating a wallet client.");
85
+ }
86
+ return createEmblemVaultWalletClient({
87
+ ...config,
88
+ sdk: this, // Pass the current SDK instance
89
+ });
20
90
  }
21
91
 
22
- // Example method structure
23
- generateUploadUrl() {
24
- // Implementation goes here
92
+ /**
93
+ * Creates a Solana Wallet Client instance powered by the Emblem Vault TEE signer.
94
+ *
95
+ * @param config - Configuration specific to the Solana wallet client, like the walletId.
96
+ * @returns An EmblemVaultSolanaWalletClient instance.
97
+ */
98
+ createSolanaWalletClient(config: Omit<EmblemVaultSolanaWalletClientConfig, 'sdk'>): EmblemVaultSolanaWalletClient {
99
+ if (!this.apiKey) {
100
+ throw new Error("SDK must be initialized with an API key before creating a wallet client.");
101
+ }
102
+ return createEmblemVaultSolanaWalletClient({
103
+ ...config,
104
+ sdk: this, // Pass the current SDK instance
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Ethereum Convenience
110
+ *
111
+ * @param config - Configuration specific to the Solana wallet client, like the walletId.
112
+ * @returns An EmblemVaultSolanaWalletClient instance.
113
+ */
114
+ async getConnectedEthAccount(): Promise<string> {
115
+ if (!this.hasProvider("ethereum")) {
116
+ await this.getOrDetectProvider("ethereum");
117
+ }
118
+ return (await this.getProvider("ethereum").eth.getAccounts())[0];
25
119
  }
26
120
 
27
121
  // ** Asset Metadata **
28
122
  //
29
- getAssetMetadata(projectName: string, strict: boolean = false) {
123
+ getCuratedAssetMetadata(projectName: string, strict: boolean = false, overrideFunc: Function | null = null) {
124
+ return this.getAssetMetadata(projectName, strict, overrideFunc);
125
+ }
126
+ // @deprecated
127
+ getAssetMetadata(projectName: string, strict: boolean = false, overrideFunc: Function | null = null) {
30
128
  genericGuard(projectName, "string", "projectName");
31
- const NFT_DATA_ARR = metadataObj2Arr(NFT_DATA)
129
+ const NFT_DATA_ARR = overrideFunc && typeof overrideFunc === 'function' ? metadataObj2Arr(overrideFunc()) : metadataObj2Arr(NFT_DATA);
32
130
  let filtered = strict ?
33
- NFT_DATA_ARR.filter(item => item.projectName === projectName) :
34
- NFT_DATA_ARR.filter(item => item.projectName.toLowerCase() === projectName.toLowerCase());
131
+ NFT_DATA_ARR.filter((item: any) => item.projectName === projectName) :
132
+ NFT_DATA_ARR.filter((item: any) => item.projectName.toLowerCase() === projectName.toLowerCase());
35
133
  return filtered
36
134
  }
37
135
 
38
- getAllAssetMetadata() {
39
- return metadataObj2Arr(NFT_DATA)
136
+ getAllCuratedAssetMetadata(overrideFunc: Function | null = null) {
137
+ return this.getAllAssetMetadata(overrideFunc);
138
+ }
139
+ // @deprecated
140
+ getAllAssetMetadata(overrideFunc: Function | null = null) {
141
+ if (overrideFunc && typeof overrideFunc === 'function') {
142
+ return overrideFunc();
143
+ }
144
+ const NFT_DATA_ARR = metadataObj2Arr(NFT_DATA);
145
+ return NFT_DATA_ARR
146
+ }
147
+
148
+ /**
149
+ * @deprecated
150
+ * This method is deprecated and will be removed in a future version.
151
+ * Please use `getInventoryAssetMetadataProject` instead.
152
+ */
153
+ async getRemoteAssetMetadataProjectList(overrideFunc: Function | null = null) {
154
+ const url = `${this.v3Url}/asset_metadata/projects`;
155
+ const NFT_DATA_ARR = overrideFunc && typeof overrideFunc === 'function' ? overrideFunc(this.apiKey) : await fetchData(url, this.apiKey);
156
+ return NFT_DATA_ARR
40
157
  }
41
158
 
42
- getRemoteAssetMetadataProjectList() {
43
- return fetchData(`${this.v3Url}/asset_metadata/projects`, this.apiKey);
159
+ async getInventoryAssetMetadataProject(projectName?: string, overrideFunc: Function | null = null) {
160
+ const url = `${this.v3Url}/asset_metadata/projects`;
161
+ const NFT_DATA_ARR = overrideFunc && typeof overrideFunc === 'function' ? overrideFunc(this.apiKey, {project: projectName}) : await fetchData(url, this.apiKey, projectName?'POST':undefined, projectName? {project: projectName}:undefined);
162
+ NFT_DATA_ARR && (await NFT_DATA_ARR).map((item: any) => { item.asset_name = item.assetName; }); // Backward compatibility
163
+ return NFT_DATA_ARR
44
164
  }
45
165
 
46
- getRemoteAssetMetadata(asset_name: string) {
47
- return fetchData(`${this.v3Url}/asset_metadata/${asset_name}`, this.apiKey);
166
+ async getInventoryAssetMetadata(asset_name: string, overrideFunc: Function | null = null) {
167
+ const url = `${this.v3Url}/asset_metadata/${asset_name}`;
168
+ const NFT_DATA_ARR = overrideFunc && typeof overrideFunc === 'function' ? overrideFunc(this.apiKey) : await fetchData(url, this.apiKey);
169
+ return NFT_DATA_ARR
48
170
  }
49
171
 
50
- getRemoteAssetMetadataVaultedProjectList() {
51
- return fetchData(`${this.v3Url}/asset_metadata/projects/vaulted`, this.apiKey);
172
+ async getInventoryAssetMetadataVaultedProjectList(overrideFunc: Function | null = null) {
173
+ const url = `${this.v3Url}/asset_metadata/projects/vaulted`;
174
+ const NFT_DATA_ARR = overrideFunc && typeof overrideFunc === 'function' ? overrideFunc(this.apiKey) : await fetchData(url, this.apiKey);
175
+ return NFT_DATA_ARR
52
176
  }
53
177
 
54
- getAllProjects() {
55
- const NFT_DATA_ARR = metadataObj2Arr(NFT_DATA)
178
+ getAllCuratedProjects(overrideFunc: Function | null = null) {
179
+ const NFT_DATA_ARR = overrideFunc && typeof overrideFunc === 'function' ? metadataObj2Arr(overrideFunc()) : metadataObj2Arr(NFT_DATA)
56
180
  const projects = metadataAllProjects(NFT_DATA_ARR)
57
181
  return projects
58
182
  }
59
183
 
60
184
  // ** Curated **
61
185
  //
62
- async fetchCuratedContracts(hideUnMintable: boolean = false, overrideFunc: Function | boolean = false): Promise<CuratedCollectionsResponse> {
186
+ async fetchCuratedContracts(hideUnMintable: boolean = false, overrideFunc: Function | null = null): Promise<CuratedCollectionsResponse> {
63
187
  let url = `${this.baseUrl}/curated`;
64
188
  // Fetch using URL or override function
65
- let data = typeof overrideFunc === 'function' ? await overrideFunc() : await fetchData(url, this.apiKey);
189
+ let data = overrideFunc? await overrideFunc(this.apiKey) : await fetchData(url, this.apiKey);
66
190
  // Filter out collections that are not mintable
67
191
  data = hideUnMintable? data.filter((collection: Collection) => collection.mintable): data;
68
192
 
@@ -76,82 +200,82 @@ class EmblemVaultSDK {
76
200
  item[key] = template[key];
77
201
  });
78
202
  // Return a new object that combines the properties of the item and the template
79
- // return { ...item, ...template };
80
- return item;
203
+ return { ...item, ...template, mintTemplate: template.generateCreateTemplate(item) };
204
+ // return item;
81
205
  });
82
206
  return data
83
207
  }
84
208
 
85
- async fetchCuratedContractByName(name: string, contracts: any = false): Promise<Collection | null> {
86
- !contracts ? contracts = await this.fetchCuratedContracts(): null
209
+ async fetchCuratedContractByName(name: string, contracts: any = false, overrideFunc: Function | null = null): Promise<Collection | null> {
210
+ !contracts ? contracts = overrideFunc? await overrideFunc(this.apiKey, {name}) : await this.fetchCuratedContracts(): null
87
211
  let contract = contracts.find((contract: Collection) => contract.name === name);
88
212
  return contract || null;
89
213
  }
90
214
 
91
- async createCuratedVault(template: any, callback: any = null): Promise<Vault> {
215
+ async createCuratedVault(template: any, callback: any = null, overrideFunc: Function | null = null): Promise<Vault> {
92
216
  templateGuard(template);
93
217
  template.chainId == 1? delete template.targetContract[5]: delete template.targetContract[1]
94
218
  let url = `${this.baseUrl}/create-curated`;
95
219
  if (callback) { callback(`creating Vault for user`, template.toAddress)}
96
- let vaultCreationResponse = await fetchData(url, this.apiKey, 'POST', template);
220
+ let vaultCreationResponse = overrideFunc? await overrideFunc(this.apiKey, template): await fetchData(url, this.apiKey, 'POST', template);
97
221
  if (callback) { callback(`created Vault tokenId`, vaultCreationResponse.data.tokenId)}
98
222
  return vaultCreationResponse.data
99
223
  }
100
224
 
101
- async refreshOwnershipForTokenId(tokenId: string, callback: any = null): Promise<Ownership[]> {
225
+ async refreshOwnershipForTokenId(tokenId: string, callback: any = null, overrideFunc: Function | null = null): Promise<Ownership[]> {
102
226
  genericGuard(tokenId, "string", "tokenId");
103
227
  let url = `${this.baseUrl}/refreshBalanceForTokenId`;
104
- let response = await fetchData(url, this.apiKey, 'POST', {tokenId});
228
+ let response = overrideFunc? await overrideFunc(this.apiKey, {tokenId}): await fetchData(url, this.apiKey, 'POST', {tokenId});
105
229
  if (callback) { callback(`Refreshed ownership for`, tokenId)}
106
230
  return response;
107
231
  }
108
232
 
109
- async refreshOwnershipForAccount(account: string, callback: any = null): Promise<Ownership[]> {
233
+ async refreshOwnershipForAccount(account: string, callback: any = null, overrideFunc: Function | null = null): Promise<Ownership[]> {
110
234
  genericGuard(account, "string", "account");
111
235
  let url = `${this.baseUrl}/refreshBalanceForAccount`;
112
- let response = await fetchData(url, this.apiKey, 'POST', {account});
236
+ let response = overrideFunc? await overrideFunc(this.apiKey, {account}): await fetchData(url, this.apiKey, 'POST', {account});
113
237
  if (callback) { callback(`Refreshed ownership for`, account)}
114
238
  return response;
115
239
  }
116
240
 
117
- async fetchMetadata(tokenId: string, callback: any = null): Promise<MetaData> {
241
+ async fetchMetadata(tokenId: string, callback: any = null, overrideFunc: Function | null = null): Promise<MetaData> {
118
242
  genericGuard(tokenId, "string", "tokenId");
119
243
  if (callback) { callback('getting Metadata')}
120
244
  let url = `${this.baseUrl}/meta/${tokenId}`;
121
- let metadata = await fetchData(url, this.apiKey);
245
+ let metadata = overrideFunc? await overrideFunc(this.apiKey, {tokenId}): await fetchData(url, this.apiKey);
122
246
  if (callback) { callback('received Metadata', metadata.tokenId)}
123
247
  return metadata;
124
248
  }
125
249
 
126
- async refreshBalance(tokenId: string, callback: any = null): Promise<MetaData> {
250
+ async refreshBalance(tokenId: string, callback: any = null, overrideFunc: Function | null = null): Promise<Balance[]> {
127
251
  genericGuard(tokenId, "string", "tokenId");
128
252
  if (callback) { callback('refreshing Balance')}
129
253
  let url = `${this.v3Url}/vault/balance/${tokenId}?live=true`;
130
- let balance = await fetchData(url, this.apiKey);
131
- if (callback) { callback('received Balance', balance.balances)}
132
- return balance?.balances || [];
254
+ let balance = overrideFunc? await overrideFunc(this.apiKey, {tokenId}): await fetchData(url, this.apiKey);
255
+ if (callback) { callback('received Balance', balance.values)}
256
+ return balance?.values || [];
133
257
  }
134
258
 
135
- async fetchVaultsOfType(vaultType: string, address: string): Promise<any> {
259
+ async fetchVaultsOfType(vaultType: string, address: string, overrideFunc: Function | null = null): Promise<any> {
136
260
  genericGuard(vaultType, "string", "vaultType");
137
261
  genericGuard(address, "string", "address");
138
262
  let url = `${this.baseUrl}/myvaults/${address}?vaultType=${vaultType}`;
139
- let vaults = await fetchData(url, this.apiKey);
263
+ let vaults = overrideFunc? await overrideFunc(this.apiKey, {vaultType, address}): await fetchData(url, this.apiKey);
140
264
  return vaults;
141
265
  }
142
266
 
143
- async generateJumpReport(address: string, hideUnMintable: boolean = false) {
267
+ async generateJumpReport(address: string, hideUnMintable: boolean = false, overrideFunc: Function | null = null) {
144
268
  let vaultType = "unclaimed"
145
269
  let curated = await this.fetchCuratedContracts();
146
270
  return new Promise(async (resolve, reject) => {
147
271
  try {
148
272
  let map: { [key: string]: any } = {};
149
- let vaults = await this.fetchVaultsOfType(vaultType, address);
273
+ let vaults = overrideFunc? await overrideFunc('vaults_of_type', this.apiKey, {vaultType, address}): await this.fetchVaultsOfType(vaultType, address);
150
274
  for (let vaultIndex = 0; vaultIndex < vaults.length; vaultIndex++) {
151
275
  let item = vaults[vaultIndex];
152
276
  let balances = item.ownership.balances || [];
153
277
  if (item.targetContract) {
154
- let vaultTargetContract: any = await this.fetchCuratedContractByName(item.targetContract.name, curated);
278
+ let vaultTargetContract: any = overrideFunc? await overrideFunc('curated_contract_by_name', this.apiKey, {name: item.targetContract.name}): await this.fetchCuratedContractByName(item.targetContract.name, curated);
155
279
  let to = [];
156
280
  for (let contractIndex = 0; contractIndex < curated.length; contractIndex++) {
157
281
  let contract: any = curated[contractIndex];
@@ -177,15 +301,15 @@ class EmblemVaultSDK {
177
301
  });
178
302
  }
179
303
 
180
- async generateMintReport(address: string, hideUnMintable: boolean = false) {
181
- let vaults = await this.fetchVaultsOfType("created", address)
304
+ async generateMintReport(address: string, hideUnMintable: boolean = false, overrideFunc: Function | null = null) {
305
+ let vaults = await this.fetchVaultsOfType("created", address, overrideFunc)
182
306
  let curated = await this.fetchCuratedContracts();
183
307
  let map: { [key: string]: any } = {};
184
308
  return new Promise(async (resolve, reject) => {
185
309
  try {
186
310
  vaults.forEach(async (vault: any) => {
187
- if (vault.targetContract) {
188
- let targetVault: any = await this.fetchCuratedContractByName(vault.targetContract.name, curated);
311
+ if (vault.targetContract) {
312
+ let targetVault: any = overrideFunc? await overrideFunc(this.apiKey, {name: vault.targetContract.name}): await this.fetchCuratedContractByName(vault.targetContract.name, curated);
189
313
  let balance = vault.balances && vault.balances.length > 0 ? vault.balances : vault.ownership && vault.ownership.balances && vault.ownership.balances.length > 0? vault.ownership.balances: []
190
314
  let allowed = targetVault.allowed(balance, targetVault)
191
315
  if (allowed || !hideUnMintable) {
@@ -206,18 +330,18 @@ class EmblemVaultSDK {
206
330
  });
207
331
  }
208
332
 
209
- async generateMigrateReport(address: string, hideUnMintable: boolean = false) {
333
+ async generateMigrateReport(address: string, hideUnMintable: boolean = false, overrideFunc: Function | null = null) {
210
334
  let vaultType = "unclaimed"
211
335
  let curated = await this.fetchCuratedContracts();
212
336
  return new Promise(async (resolve, reject) => {
213
337
  try {
214
338
  let map: { [key: string]: any } = {};
215
- let vaults = await this.fetchVaultsOfType(vaultType, address);
339
+ let vaults = overrideFunc? await overrideFunc(this.apiKey, {vaultType, address}): await this.fetchVaultsOfType(vaultType, address);
216
340
  for (let vaultIndex = 0; vaultIndex < vaults.length; vaultIndex++) {
217
341
  let item = vaults[vaultIndex];
218
342
  let balances = item.ownership.balances || [];
219
343
  if (!item.targetContract) {
220
- // let vaultTargetContract: any = await this.fetchCuratedContractByName(item.targetContract.name, curated);
344
+ // let vaultTargetContract: any = await this.fetchCuratedContractByName(item.targetContract.name);
221
345
  let to = [];
222
346
  for (let contractIndex = 0; contractIndex < curated.length; contractIndex++) {
223
347
  let contract: any = curated[contractIndex];
@@ -248,39 +372,46 @@ class EmblemVaultSDK {
248
372
  // Function to load web3 dynamically and attach it to the window object
249
373
  async loadWeb3(): Promise<any | undefined> {
250
374
  try {
251
- // Dynamically import the Web3 module
252
- const { default: Web3 } = await import('web3');
253
-
254
- // Check if MetaMask (window.ethereum) is available
255
- if (window.ethereum) {
256
- await window.ethereum.request({ method: 'eth_requestAccounts' });
257
- // Initialize Web3 with MetaMask's provider
258
- const web3 = new Web3(window.ethereum);
259
-
260
- // Attach Web3 to the window object
261
- window.web3 = web3;
262
-
263
- return web3;
264
- } else {
265
- console.error('MetaMask is not installed!');
266
- return undefined;
375
+ const provider = await this.getOrDetectProvider('ethereum') as EthereumProvider;
376
+ // Check if it's our adapter and return the raw Web3 instance
377
+ if (provider instanceof Web3ProviderAdapter) {
378
+ return provider.getRawWeb3();
267
379
  }
380
+ // If it's a generic EIP-1193 provider, we might need to wrap it if direct Web3 usage is required
381
+ // For now, let's assume the adapter covers the primary case (MetaMask)
382
+ console.warn('loadWeb3: Detected Ethereum provider is not a Web3 instance. Returning the provider object itself.');
383
+ return provider;
268
384
  } catch (error) {
269
- console.error('Error loading Web3 or connecting to MetaMask', error);
385
+ console.error('Could not load or detect Ethereum provider:', error);
270
386
  return undefined;
271
387
  }
272
388
  }
273
389
 
274
- async performMintChain(web3: any, tokenId: string, collectionName: string, callback: any = null) {
275
- let collection = await this.fetchCuratedContractByName(collectionName);
390
+ /**
391
+ * Performs a mint operation on the blockchain.
392
+ * @param web3 - The web3 instance to use for the transaction.
393
+ * @param tokenId - The ID of the token to mint.
394
+ * @param callback - Optional callback function to handle the transaction.
395
+ * @returns A promise that resolves to the mint response.
396
+ * @deprecated Use `performMintHelper` instead.
397
+ */
398
+ async performMintChain(web3: any, tokenId: string, callback: any = null) {
276
399
  let mintRequestSig = await this.requestLocalMintSignature(web3, tokenId, callback);
277
- let remoteMintSig = await this.requestRemoteMintSignature(web3, tokenId, mintRequestSig, callback);
278
- let quote = await this.getQuote(web3, collection? collection.price: remoteMintSig._price/1000000, callback);
279
- let ethToSend = quote.mul(BigNumber.from(10).pow(6))
280
- let mintResponse = await this.performMint(web3, ethToSend, remoteMintSig, callback);
400
+ let remoteMintSig = await this.requestRemoteMintSignature(web3, tokenId, mintRequestSig, callback);
401
+ let mintResponse = await this.performMint(web3, remoteMintSig, callback);
281
402
  return {mintResponse}
282
403
  }
283
404
 
405
+ /**
406
+ * Stub for new mint chain helper
407
+ * @param amount - The amount of tokens to mint.
408
+ * @param callback - Optional callback function to handle the transaction.
409
+ * @returns A promise that resolves to the mint response.
410
+ */
411
+ async performMintHelper( amount: number, callback?: any): Promise<BigNumber> {
412
+ throw new Error('Not implemented');
413
+ }
414
+
284
415
  async performClaimChain(web3: any, tokenId: string, serialNumber: any, callback: any = null) {
285
416
  let sig = await this.requestLocalClaimSignature(web3, tokenId, serialNumber, callback)
286
417
  let jwt = await this.requestRemoteClaimToken(web3, tokenId, sig, callback)
@@ -288,6 +419,14 @@ class EmblemVaultSDK {
288
419
  return await this.decryptVaultKeys(tokenId, dkeys, callback)
289
420
  }
290
421
 
422
+ /**
423
+ * Stub for new mint signature request
424
+ * @param web3 - The web3 instance to use for the transaction.
425
+ * @param tokenId - The ID of the token to mint.
426
+ * @param callback - Optional callback function to handle the transaction.
427
+ * @returns A promise that resolves to the mint signature.
428
+ * @deprecated Use `requestV3LocalMintSignature` instead.
429
+ */
291
430
  async requestLocalMintSignature(web3: any, tokenId: string, callback: any = null) {
292
431
  if (callback) { callback('requesting User Mint Signature')}
293
432
  const message = `Curated Minting: ${tokenId.toString()}`;
@@ -297,51 +436,130 @@ class EmblemVaultSDK {
297
436
  return signature;
298
437
  }
299
438
 
300
- async requestLocalClaimSignature(web3: any, tokenId: string, serialNumber: any, callback: any = null) {
301
- if (callback) { callback('requesting User Claim Signature')}
302
- const message = `Claim: ${serialNumber? serialNumber.toString(): tokenId.toString()}`;
303
- const accounts = await web3.eth.getAccounts();
304
- const signature = await web3.eth.personal.sign(message, accounts[0], '');
439
+ /**
440
+ * Requests a signature for a curated minting operation. (ONLY ETHEREUM FOR NOW)
441
+ * @param tokenId - The ID of the token to mint.
442
+ * @param callback - Optional callback function to handle the transaction.
443
+ * @param overrideFunc - Optional function to override the default behavior.
444
+ * @returns A promise that resolves to the mint signature.
445
+ */
446
+ async requestV3LocalMintSignature(tokenId: string, callback: any = null, overrideFunc: Function | null = null): Promise<v3LocalMintSignature> {
447
+ if (callback) { callback('requesting Owner Mint Signature')}
448
+ const provider = await this.getOrDetectProvider('ethereum');
449
+ const rawBlockNumber = await provider.eth.getBlockNumber();
450
+ const blockNumber = Number(rawBlockNumber).toString();
451
+ const message = `Curated Minting: ${tokenId.toString()} \n\nat Block# ${blockNumber}`;
452
+ const account = await this.getConnectedEthAccount();
453
+ if (!account) {
454
+ throw new Error('No connected wallet found');
455
+ }
456
+ const signature = overrideFunc? await overrideFunc(message, account): await provider.eth.personal.sign(message, account, callback? callback: '');
305
457
  if (callback) { callback(`signature`, signature)}
306
- return signature;
458
+ return {message, signature};
459
+ }
460
+
461
+ /**
462
+ * Requests a signature for a curated minting operation. (ONLY ETHEREUM FOR NOW)
463
+ * @param tokenId - The ID of the token to mint.
464
+ * @param signature - The signature for the curated minting operation.
465
+ * @param callback - Optional callback function to handle the transaction.
466
+ * @param overrideFunc - Optional function to override the default behavior.
467
+ * @returns A promise that resolves to the remote mint signature.
468
+ * @deprecated Use `requestV3RemoteMintSignature` instead.
469
+ */
470
+ async requestRemoteMintSignature(web3: any, tokenId: string, signature: string, callback: any = null, overrideFunc: Function | null = null) {
471
+ if (callback) { callback('requesting Remote Mint signature')}
472
+ const chainId = await web3.eth.getChainId();
473
+ let url = `${this.baseUrl}/mint-curated`;
474
+ let mintRequestBody = {method: 'buyWithSignedPrice', tokenId: tokenId, signature: signature, chainId: chainId.toString()}
475
+ let remoteMintResponse = overrideFunc? await overrideFunc(url, this.apiKey, 'POST', mintRequestBody): await fetchData(url, this.apiKey, 'POST', mintRequestBody);
476
+ if (remoteMintResponse.error) {
477
+ throw new Error(remoteMintResponse.error)
478
+ }
479
+ if (callback) { callback(`remote Mint signature`, remoteMintResponse)}
480
+ return remoteMintResponse
307
481
  }
308
482
 
309
- async requestRemoteMintSignature(web3: any, tokenId: string, signature: string, callback: any = null) {
483
+ /**
484
+ * Requests a signature for a curated minting operation. (ONLY ETHEREUM FOR NOW)
485
+ * @param tokenId - The ID of the token to mint.
486
+ * @param signature - The signature for the curated minting operation.
487
+ * @param callback - Optional callback function to handle the transaction.
488
+ * @param overrideFunc - Optional function to override the default behavior.
489
+ * @returns A promise that resolves to the remote mint signature.
490
+ */
491
+ async requestV3RemoteMintSignature(tokenId: string, signature: string, callback: any = null, overrideFunc: Function | null = null) {
310
492
  if (callback) { callback('requesting Remote Mint signature')}
311
- const chainId = await web3.eth.getChainId();
493
+ const chainId = (await this.getOrDetectProvider('ethereum')).eth.getChainId();
312
494
  let url = `${this.baseUrl}/mint-curated`;
313
- let remoteMintResponse = await fetchData(url, this.apiKey, 'POST', {method: 'buyWithQuote', tokenId: tokenId, signature: signature, chainId: chainId.toString()});
495
+ const mintRequestBody = {method: 'buyWithSignedPrice', tokenId: tokenId, signature: signature, chainId: chainId.toString(), enhanced: true};
496
+ let remoteMintResponse = overrideFunc? await overrideFunc(url, this.apiKey, 'POST', mintRequestBody): await fetchData(url, this.apiKey, 'POST', mintRequestBody);
314
497
  if (remoteMintResponse.error) {
315
498
  throw new Error(remoteMintResponse.error)
316
499
  }
317
500
  if (callback) { callback(`remote Mint signature`, remoteMintResponse)}
318
501
  return remoteMintResponse
319
- }
502
+ }
503
+
504
+ async requestLocalClaimSignature(web3: any, tokenId: string, serialNumber: any, callback: any = null) {
505
+ if (callback) { callback('requesting User Claim Signature')}
506
+ const message = `Claim: ${serialNumber? serialNumber.toString(): tokenId.toString()}`;
507
+ const accounts = await web3.eth.getAccounts();
508
+ const signature = await web3.eth.personal.sign(message, accounts[0], '');
509
+ if (callback) { callback(`signature`, signature)}
510
+ return signature;
511
+ }
320
512
 
321
- async requestRemoteClaimToken(web3: any, tokenId: string, signature: string, callback: any = null) {
513
+ async requestRemoteClaimToken(web3: any, tokenId: string, signature: string, callback: any = null, overrideFunc: Function | null = null) {
322
514
  if (callback) { callback('requesting Remote Claim token')}
323
515
  const chainId = await web3.eth.getChainId();
324
516
  let url = `${this.sigUrl}/sign`;
325
- let remoteClaimResponse = await fetchData(url, this.apiKey, 'POST', {signature: signature, tokenId: tokenId}, {chainid: chainId.toString()});
517
+ let remoteClaimResponse = overrideFunc? await overrideFunc(this.apiKey, {signature: signature, tokenId: tokenId, chainid: chainId.toString()}): await fetchData(url, this.apiKey, 'POST', {signature: signature, tokenId: tokenId}, {chainid: chainId.toString()});
326
518
  if (callback) { callback(`remote Claim token`, remoteClaimResponse)}
327
519
  return remoteClaimResponse
328
520
  }
329
521
 
330
- async requestRemoteKey(tokenId: string, jwt: any, callback: any = null) {
522
+ async requestRemoteKey(tokenId: string, jwt: any, callback: any = null, overrideFunc: Function | null = null) {
331
523
  if (callback) { callback('requesting Remote Key')}
332
- let dkeys = await getTorusKeys(tokenId, jwt.token)
524
+ let dkeys = overrideFunc? await overrideFunc(this.apiKey, {tokenId: tokenId, jwt: jwt.token}): await getTorusKeys(tokenId, jwt.token)
333
525
  if (callback) { callback(`remote Key`, dkeys)}
334
526
  return dkeys
335
527
  }
336
528
 
337
- async decryptVaultKeys(tokenId: string, dkeys: any, callback: any = null) {
529
+ async decryptVaultKeys(tokenId: string, dkeys: any, callback: any = null, overrideFunc: Function | null = null) {
338
530
  if (callback) { callback('decrypting Vault Keys')}
339
- let metadata: any = await this.fetchMetadata(tokenId);
531
+ let metadata: any = overrideFunc? await overrideFunc(this.apiKey, {tokenId: tokenId}): await this.fetchMetadata(tokenId);
340
532
  let ukeys = await decryptKeys(metadata.ciphertextV2, dkeys, metadata.addresses)
341
533
  if (callback) { callback(`remote Key`, ukeys)}
342
534
  return ukeys
343
535
  }
344
536
 
537
+ async recoverSignerFromMessage(message: string, signature: string, overrideFunc: Function | null = null): Promise<string> {
538
+ const provider = await this.getOrDetectProvider('ethereum');
539
+ return overrideFunc? await overrideFunc(message, signature): await provider.eth.personal.recover(message, signature);
540
+ }
541
+
542
+ /**
543
+ * ** Emblem Vault AI **
544
+ *
545
+ * Be sure to allow api key requests, or api_key_hash and auth sig (wallet, socialAuth, oAuth)
546
+ * Here we will begin using the aiApiKey and the aiUrl to communicate with the ai vault system
547
+ *
548
+ */
549
+
550
+ async vaultInfoFromApiKey(aiApiKey?: string, full?: boolean, overrideFunc: Function | null = null): Promise<AiVaultInfo> {
551
+ const url = `${this.aiUrl}/vault/${full ? 'info-complete' : 'info'}`;
552
+ const selectedKey = aiApiKey ? aiApiKey : this.aiApiKey ? this.aiApiKey : '';
553
+ const actionFunction = overrideFunc && typeof overrideFunc === 'function' ? overrideFunc: fetchData;
554
+ const vaultDetails = await actionFunction(url, selectedKey, 'POST', null);
555
+ // vaultDetails.computedEthAddress = ethers.utils.computeAddress(vaultDetails.pkp.pub_key.replace('0x',''));
556
+ return vaultDetails;
557
+ }
558
+
559
+ /**
560
+ * @deprecated This method is deprecated and will be removed in a future version.
561
+ * Please use alternative methods for price quotation.
562
+ */
345
563
  async getQuote(web3: any, amount: number, callback: any = null) {
346
564
  if (callback) { callback('requesting Quote')}
347
565
  let quoteContract = await getQuoteContractObject(web3);
@@ -351,7 +569,8 @@ class EmblemVaultSDK {
351
569
  return quote
352
570
  }
353
571
 
354
- async performMint(web3: any, quote: any, remoteMintSig: any, callback: any = null) {
572
+ // todo add contract overrides
573
+ async performMint(web3: any, remoteMintSig: any, callback: any = undefined) {
355
574
  // async performMint(web3, quote, remoteMintSig, callback = null) {
356
575
  if (callback) { callback('performing Mint') }
357
576
  const accounts = await web3.eth.getAccounts();
@@ -360,9 +579,10 @@ class EmblemVaultSDK {
360
579
  // Get current gas price from the network
361
580
  const gasPrice = await web3.eth.getGasPrice();
362
581
 
363
- let createdTxObject = handlerContract.methods.buyWithQuote(
364
- remoteMintSig._nftAddress,
365
- remoteMintSig._price,
582
+ let createdTxObject = handlerContract.methods.buyWithSignedPrice(
583
+ remoteMintSig._nftAddress,
584
+ '0x0000000000000000000000000000000000000000',
585
+ remoteMintSig._price.hex,
366
586
  remoteMintSig._to,
367
587
  remoteMintSig._tokenId,
368
588
  remoteMintSig._nonce,
@@ -372,12 +592,12 @@ class EmblemVaultSDK {
372
592
  )
373
593
 
374
594
  // Estimate gas limit for the transaction
375
- const gasLimit = await createdTxObject.estimateGas({ from: accounts[0], value: Number(quote) });
595
+ const gasLimit = await createdTxObject.estimateGas({ from: accounts[0], value: remoteMintSig._price.hex });
376
596
 
377
597
  // Execute the transaction with the specified gas price and estimated gas limit
378
598
  let mintResponse = await createdTxObject.send({
379
599
  from: accounts[0],
380
- value: Number(quote),
600
+ value: remoteMintSig._price.hex,
381
601
  gasPrice: gasPrice, // Use the current gas price
382
602
  gas: gasLimit // Use the estimated gas limit
383
603
  }).on('transactionHash', (hash: any) => {
@@ -593,13 +813,11 @@ class EmblemVaultSDK {
593
813
  declare global {
594
814
  interface Window {
595
815
  EmblemVaultSDK: any;
596
- web3: any;
597
- ethereum: any
816
+ // web3: any;
817
+ // ethereum: any
598
818
  }
599
819
  }
600
820
 
601
821
  if (typeof window !== 'undefined') {
602
822
  window.EmblemVaultSDK = EmblemVaultSDK;
603
823
  }
604
-
605
- export default EmblemVaultSDK;