emblem-vault-sdk 2.9.1 → 2.10.0
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.
- package/dist/bundle.js +36862 -22672
- package/dist/constants.js +35 -0
- package/dist/evm-operations.js +303 -0
- package/dist/index.js +107 -4
- package/dist/signing-messages.js +19 -0
- package/dist/utils.js +40 -0
- package/dist/vault-utils.js +71 -0
- package/docs/bundle.js +36862 -22672
- package/docs/index.html +8 -2
- package/package.json +5 -3
- package/readme.md +32 -0
- package/src/constants.ts +47 -0
- package/src/evm-operations.ts +391 -0
- package/src/index.ts +147 -6
- package/src/signing-messages.ts +16 -0
- package/src/types.ts +96 -0
- package/src/utils.ts +41 -2
- package/src/vault-utils.ts +89 -0
- package/types/constants.d.ts +17 -0
- package/types/evm-operations.d.ts +4 -0
- package/types/index.d.ts +26 -2
- package/types/signing-messages.d.ts +4 -0
- package/types/types.d.ts +87 -0
- package/types/utils.d.ts +1 -0
- package/types/vault-utils.d.ts +34 -0
package/src/index.ts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
import { BigNumber } from '@ethersproject/bignumber'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import type {
|
|
3
|
+
Collection,
|
|
4
|
+
CuratedCollectionsResponse,
|
|
5
|
+
MetaData,
|
|
6
|
+
Ownership,
|
|
7
|
+
Vault,
|
|
8
|
+
ProgressCallback,
|
|
9
|
+
MintResult,
|
|
10
|
+
ClaimResult,
|
|
11
|
+
EmblemVaultClient,
|
|
12
|
+
SdkContext,
|
|
13
|
+
} from './types';
|
|
14
|
+
import { NFT_DATA, checkContentType, decryptKeys, fetchData, generateTemplate, genericGuard, getHandlerContract, getLegacyContract, getQuoteContractObject, getSatsConnectAddress, getTorusKeys, metadataAllProjects, metadataObj2Arr, signPSBT, templateGuard } from './utils';
|
|
5
15
|
import { generateTaprootAddressFromMnemonic, getPsbtTxnSize } from './derive';
|
|
16
|
+
import {
|
|
17
|
+
ETHEREUM_MAINNET_CHAIN_ID,
|
|
18
|
+
} from './constants';
|
|
19
|
+
import {
|
|
20
|
+
getChainConfig,
|
|
21
|
+
isV2Vault,
|
|
22
|
+
requiresOnChainUnvault,
|
|
23
|
+
getClaimIdentifier,
|
|
24
|
+
} from './vault-utils';
|
|
25
|
+
import { performMintEvm, performClaimEvm, deleteVaultEvm } from './evm-operations';
|
|
26
|
+
|
|
6
27
|
const SDK_VERSION = '__SDK_VERSION__';
|
|
7
28
|
|
|
8
29
|
class EmblemVaultSDK {
|
|
@@ -76,7 +97,7 @@ class EmblemVaultSDK {
|
|
|
76
97
|
item[key] = template[key];
|
|
77
98
|
});
|
|
78
99
|
// Return a new object that combines the properties of the item and the template
|
|
79
|
-
|
|
100
|
+
return { ...item, ...template };
|
|
80
101
|
return item;
|
|
81
102
|
});
|
|
82
103
|
return data
|
|
@@ -94,7 +115,14 @@ class EmblemVaultSDK {
|
|
|
94
115
|
let url = `${this.baseUrl}/create-curated`;
|
|
95
116
|
if (callback) { callback(`creating Vault for user`, template.toAddress)}
|
|
96
117
|
let vaultCreationResponse = await fetchData(url, this.apiKey, 'POST', template);
|
|
97
|
-
|
|
118
|
+
|
|
119
|
+
if (vaultCreationResponse?.err) {
|
|
120
|
+
if (callback) callback(`error creating Vault: ${vaultCreationResponse.msg}`)
|
|
121
|
+
return vaultCreationResponse
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const { tokenId } = vaultCreationResponse.data
|
|
125
|
+
if (callback) { callback(`created Vault ${tokenId}`)}
|
|
98
126
|
return vaultCreationResponse.data
|
|
99
127
|
}
|
|
100
128
|
|
|
@@ -132,14 +160,67 @@ class EmblemVaultSDK {
|
|
|
132
160
|
return balance?.balances || [];
|
|
133
161
|
}
|
|
134
162
|
|
|
135
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Fetch vaults of a specific type for an address.
|
|
165
|
+
* @param vaultType - The vault type: "vaulted", "unvaulted", or "created"
|
|
166
|
+
* @param address - The wallet address to fetch vaults for
|
|
167
|
+
* @param options - Optional pagination options
|
|
168
|
+
* @param options.page - Page number (1-indexed). If provided, returns paginated response.
|
|
169
|
+
* @param options.limit - Number of results per page (default: 100)
|
|
170
|
+
* @returns Array of vaults (unpaginated) or { data, pagination } object (paginated)
|
|
171
|
+
*/
|
|
172
|
+
async fetchVaultsOfType(vaultType: string, address: string, options?: { page?: number; limit?: number }): Promise<any> {
|
|
136
173
|
genericGuard(vaultType, "string", "vaultType");
|
|
137
174
|
genericGuard(address, "string", "address");
|
|
138
175
|
let url = `${this.baseUrl}/myvaults/${address}?vaultType=${vaultType}`;
|
|
176
|
+
|
|
177
|
+
// Add pagination params if provided
|
|
178
|
+
if (options?.page !== undefined || options?.limit !== undefined) {
|
|
179
|
+
if (options.page !== undefined) url += `&page=${options.page}`;
|
|
180
|
+
if (options.limit !== undefined) url += `&limit=${options.limit}`;
|
|
181
|
+
}
|
|
182
|
+
|
|
139
183
|
let vaults = await fetchData(url, this.apiKey);
|
|
140
184
|
return vaults;
|
|
141
185
|
}
|
|
142
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Fetch all vaults of a specific type, automatically handling pagination.
|
|
189
|
+
* @param vaultType - The vault type: "vaulted", "unvaulted", or "created"
|
|
190
|
+
* @param address - The wallet address to fetch vaults for
|
|
191
|
+
* @param onProgress - Optional callback for progress updates (page, totalPages, total)
|
|
192
|
+
* @returns Array of all vaults
|
|
193
|
+
*/
|
|
194
|
+
async fetchAllVaultsOfType(vaultType: string, address: string, onProgress?: (page: number, totalPages: number, total: number) => void): Promise<any[]> {
|
|
195
|
+
genericGuard(vaultType, "string", "vaultType");
|
|
196
|
+
genericGuard(address, "string", "address");
|
|
197
|
+
|
|
198
|
+
const allVaults: any[] = [];
|
|
199
|
+
let page = 1;
|
|
200
|
+
let totalPages = 1;
|
|
201
|
+
const limit = 100;
|
|
202
|
+
|
|
203
|
+
while (page <= totalPages) {
|
|
204
|
+
const result = await this.fetchVaultsOfType(vaultType, address, { page, limit });
|
|
205
|
+
|
|
206
|
+
if (result.pagination) {
|
|
207
|
+
// Paginated response
|
|
208
|
+
allVaults.push(...result.data);
|
|
209
|
+
totalPages = result.pagination.totalPages;
|
|
210
|
+
if (onProgress) {
|
|
211
|
+
onProgress(page, totalPages, result.pagination.total);
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
// Legacy non-paginated response (shouldn't happen with updated API)
|
|
215
|
+
return Array.isArray(result) ? result : [];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
page++;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return allVaults;
|
|
222
|
+
}
|
|
223
|
+
|
|
143
224
|
async generateJumpReport(address: string, hideUnMintable: boolean = false) {
|
|
144
225
|
let vaultType = "unclaimed"
|
|
145
226
|
let curated = await this.fetchCuratedContracts();
|
|
@@ -480,6 +561,66 @@ class EmblemVaultSDK {
|
|
|
480
561
|
return results;
|
|
481
562
|
}
|
|
482
563
|
|
|
564
|
+
// ========================================================================
|
|
565
|
+
// Remote Signer Methods (EmblemVaultClient) - Multi-Chain Support
|
|
566
|
+
// ========================================================================
|
|
567
|
+
|
|
568
|
+
private getSdkContext(): SdkContext {
|
|
569
|
+
return {
|
|
570
|
+
apiKey: this.apiKey,
|
|
571
|
+
baseUrl: this.baseUrl,
|
|
572
|
+
v3Url: this.v3Url,
|
|
573
|
+
sigUrl: this.sigUrl,
|
|
574
|
+
fetchMetadata: this.fetchMetadata.bind(this),
|
|
575
|
+
requestRemoteKey: this.requestRemoteKey.bind(this),
|
|
576
|
+
decryptVaultKeys: this.decryptVaultKeys.bind(this),
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
async performMintChainWithClient(
|
|
581
|
+
client: EmblemVaultClient,
|
|
582
|
+
tokenId: string,
|
|
583
|
+
chainId: number | 'solana' = ETHEREUM_MAINNET_CHAIN_ID,
|
|
584
|
+
callback?: ProgressCallback
|
|
585
|
+
): Promise<MintResult> {
|
|
586
|
+
genericGuard(tokenId, "string", "tokenId");
|
|
587
|
+
getChainConfig(chainId);
|
|
588
|
+
return performMintEvm(this.getSdkContext(), client, tokenId, chainId as number, callback);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
async performClaimChainWithClient(
|
|
592
|
+
client: EmblemVaultClient,
|
|
593
|
+
tokenId: string,
|
|
594
|
+
chainId: number | 'solana' = ETHEREUM_MAINNET_CHAIN_ID,
|
|
595
|
+
callback?: ProgressCallback
|
|
596
|
+
): Promise<ClaimResult> {
|
|
597
|
+
genericGuard(tokenId, "string", "tokenId");
|
|
598
|
+
getChainConfig(chainId);
|
|
599
|
+
|
|
600
|
+
callback?.('Fetching vault metadata...');
|
|
601
|
+
const metadata = await this.fetchMetadata(tokenId, callback);
|
|
602
|
+
const claimIdentifier = getClaimIdentifier(metadata);
|
|
603
|
+
|
|
604
|
+
// Check if this is a V2 vault by checking the deployment type (matches VaultActions.vue logic)
|
|
605
|
+
// metadata[chainId]?.type?.endsWith('V2') indicates a diamond/V2 contract
|
|
606
|
+
const deploymentInfo = (metadata as Record<string, unknown>)?.[chainId as number] as { type?: string } | undefined;
|
|
607
|
+
const vaultIsV2 = Boolean(deploymentInfo?.type?.endsWith?.('V2'));
|
|
608
|
+
const needsOnChainUnvault = requiresOnChainUnvault(metadata) && vaultIsV2;
|
|
609
|
+
|
|
610
|
+
return performClaimEvm(this.getSdkContext(), client, tokenId, chainId as number, metadata, claimIdentifier, vaultIsV2, needsOnChainUnvault, callback);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
async deleteVaultWithClient(
|
|
614
|
+
client: EmblemVaultClient,
|
|
615
|
+
tokenId: string,
|
|
616
|
+
chainId: number | 'solana' = ETHEREUM_MAINNET_CHAIN_ID,
|
|
617
|
+
callback?: ProgressCallback
|
|
618
|
+
): Promise<boolean> {
|
|
619
|
+
genericGuard(tokenId, "string", "tokenId");
|
|
620
|
+
getChainConfig(chainId);
|
|
621
|
+
return deleteVaultEvm(client, tokenId, chainId as number, callback);
|
|
622
|
+
}
|
|
623
|
+
|
|
483
624
|
// BTC
|
|
484
625
|
|
|
485
626
|
async sweepVaultUsingPhrase(phrase: string, satsPerByte: number = 20, broadcast: boolean = false) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function buildMintMessage(tokenId: string): string {
|
|
2
|
+
return `Curated Minting: ${tokenId}`;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function buildClaimMessage(identifier: string, isV2Vault: boolean): string {
|
|
6
|
+
const prefix = isV2Vault ? 'Unvault' : 'Claim';
|
|
7
|
+
return `${prefix}: ${identifier}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function buildUnvaultMessage(identifier: string): string {
|
|
11
|
+
return `Unvault: ${identifier}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function buildDeleteMessage(tokenId: string): string {
|
|
15
|
+
return `Delete: ${tokenId}`;
|
|
16
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -27,6 +27,14 @@ export type Collection = {
|
|
|
27
27
|
balanceCheckers: string[] | null;
|
|
28
28
|
tokenIdScheme: string | null;
|
|
29
29
|
generateVaultBody: Function;
|
|
30
|
+
/**
|
|
31
|
+
* Returns a template ready to send to the create vault API
|
|
32
|
+
*
|
|
33
|
+
* @param {FillCreateVaultTemplateArgs} args - Arguments to fill the template
|
|
34
|
+
* @param {_this: Collection} _this - The collection context
|
|
35
|
+
* @returns {Object} - Filled create vault template
|
|
36
|
+
*/
|
|
37
|
+
fillCreateVaultTemplate: (args: FillCreateVaultTemplateArgs, _this: Collection) => Object;
|
|
30
38
|
generateCreateTemplate: Function;
|
|
31
39
|
};
|
|
32
40
|
|
|
@@ -142,3 +150,91 @@ export type Ownership = {
|
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
export type CuratedCollectionsResponse = Collection[];
|
|
153
|
+
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// Remote Signer Types (for EmblemVaultClient integration)
|
|
156
|
+
// ============================================================================
|
|
157
|
+
|
|
158
|
+
export type ChainIdentifier = number | 'solana';
|
|
159
|
+
|
|
160
|
+
export type ProgressCallback = (message: string, data?: unknown) => void;
|
|
161
|
+
|
|
162
|
+
export interface MintResult {
|
|
163
|
+
txHash: string;
|
|
164
|
+
tokenId: string;
|
|
165
|
+
chainId: ChainIdentifier;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface ClaimResult {
|
|
169
|
+
phrase?: string;
|
|
170
|
+
privateKey?: string;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface RemoteMintSignature {
|
|
174
|
+
_nftAddress: string;
|
|
175
|
+
_price: { hex: string } | string | number;
|
|
176
|
+
_to: string;
|
|
177
|
+
_tokenId: { hex: string } | string | number;
|
|
178
|
+
_nonce: { hex: string } | string | number;
|
|
179
|
+
_signature: string;
|
|
180
|
+
serialNumber: string;
|
|
181
|
+
error?: string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface RemoteUnvaultSignature {
|
|
185
|
+
success: boolean;
|
|
186
|
+
_nftAddress: string;
|
|
187
|
+
_tokenId: { hex: string } | string | number;
|
|
188
|
+
_nonce: { hex: string } | string | number;
|
|
189
|
+
_price: { hex: string } | string | number;
|
|
190
|
+
_timestamp: { hex: string } | string | number;
|
|
191
|
+
_signature: string;
|
|
192
|
+
msg?: string;
|
|
193
|
+
err?: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ============================================================================
|
|
197
|
+
// EVM Signer Interface (matches emblem-vault-ai-signers EmblemEthersWallet)
|
|
198
|
+
// ============================================================================
|
|
199
|
+
|
|
200
|
+
export interface EvmSigner {
|
|
201
|
+
getAddress(): Promise<string>;
|
|
202
|
+
signMessage(message: string | Uint8Array): Promise<string>;
|
|
203
|
+
sendTransaction(tx: unknown): Promise<{ hash: string; wait(): Promise<unknown> }>;
|
|
204
|
+
setChainId?(chainId: number): void;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ============================================================================
|
|
208
|
+
// EmblemVaultClient Interface - matches emblem-vault-ai-signers
|
|
209
|
+
// ============================================================================
|
|
210
|
+
|
|
211
|
+
export interface EmblemVaultClient {
|
|
212
|
+
toEthersWallet(provider?: unknown): Promise<EvmSigner>;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ============================================================================
|
|
216
|
+
// SDK Context for operations modules
|
|
217
|
+
// ============================================================================
|
|
218
|
+
|
|
219
|
+
export interface SdkContext {
|
|
220
|
+
apiKey: string;
|
|
221
|
+
baseUrl: string;
|
|
222
|
+
v3Url: string;
|
|
223
|
+
sigUrl: string;
|
|
224
|
+
fetchMetadata: (tokenId: string, callback?: ProgressCallback) => Promise<MetaData>;
|
|
225
|
+
requestRemoteKey: (tokenId: string, jwt: unknown, callback?: ProgressCallback) => Promise<unknown>;
|
|
226
|
+
decryptVaultKeys: (tokenId: string, dkeys: unknown, callback?: ProgressCallback) => Promise<ClaimResult>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export interface FillCreateVaultTemplateArgs {
|
|
230
|
+
fromAddress: string,
|
|
231
|
+
toAddress: string,
|
|
232
|
+
targetAsset: {
|
|
233
|
+
name: string,
|
|
234
|
+
image: string,
|
|
235
|
+
description?: string,
|
|
236
|
+
ownedImage?: string,
|
|
237
|
+
projectName?: string
|
|
238
|
+
},
|
|
239
|
+
chainId: number,
|
|
240
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import CryptoJS from 'crypto-js'
|
|
2
|
-
import { MetaData } from "./types";
|
|
2
|
+
import { MetaData, FillCreateVaultTemplateArgs } from "./types";
|
|
3
3
|
import metadataJson from './curated/metadata.json';
|
|
4
4
|
import darkfarmsMetadataJson from './curated/darkfarms-metadata.json';
|
|
5
5
|
import dot_idMetadataJson from './curated/dot_id.json';
|
|
@@ -552,6 +552,40 @@ export function generateTemplate(record: any) {
|
|
|
552
552
|
|
|
553
553
|
return nameAndImage
|
|
554
554
|
},
|
|
555
|
+
fillCreateVaultTemplate: (args: FillCreateVaultTemplateArgs, _this: any) => {
|
|
556
|
+
const template = _this.generateCreateTemplate(_this)
|
|
557
|
+
|
|
558
|
+
if (args.fromAddress) {
|
|
559
|
+
template.fromAddress = args.fromAddress
|
|
560
|
+
} else {
|
|
561
|
+
throw new Error("fromAddress is required to create vault")
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (args.toAddress) {
|
|
565
|
+
template.toAddress = args.toAddress
|
|
566
|
+
} else {
|
|
567
|
+
throw new Error("toAddress is required to create vault")
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (args.chainId) {
|
|
571
|
+
const chainIdAsString = String(args.chainId)
|
|
572
|
+
template.targetContract = {
|
|
573
|
+
name: template.targetContract.name,
|
|
574
|
+
[chainIdAsString]: template.targetContract[chainIdAsString]
|
|
575
|
+
}
|
|
576
|
+
template.chainId = args.chainId
|
|
577
|
+
} else {
|
|
578
|
+
throw new Error("chainId is required to create vault")
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
if (args.targetAsset) {
|
|
582
|
+
Object.assign(template.targetAsset, args.targetAsset)
|
|
583
|
+
} else {
|
|
584
|
+
template.targetAsset = undefined
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
return template
|
|
588
|
+
},
|
|
555
589
|
generateCreateTemplate: (_this: any) =>{
|
|
556
590
|
let template = {
|
|
557
591
|
fromAddress: { type: "user-provided" },
|
|
@@ -914,4 +948,9 @@ export async function signPSBT(psbtBase64: any, paymentAddress: any, indexes: nu
|
|
|
914
948
|
});
|
|
915
949
|
}
|
|
916
950
|
|
|
917
|
-
|
|
951
|
+
export function parseBigIntValue(value: unknown): bigint {
|
|
952
|
+
if (typeof value === 'object' && value !== null && 'hex' in value) {
|
|
953
|
+
return BigInt((value as { hex: string }).hex);
|
|
954
|
+
}
|
|
955
|
+
return BigInt(String(value));
|
|
956
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ChainConfig, SUPPORTED_CHAINS } from "./constants";
|
|
2
|
+
|
|
3
|
+
export function isV2Vault(metadata: { targetContract?: { name?: string } }): boolean {
|
|
4
|
+
return Boolean(metadata.targetContract?.name);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function requiresOnChainUnvault(metadata: { status?: string; sealed?: boolean; live?: boolean }): boolean {
|
|
8
|
+
return metadata.status === 'unclaimed' && !metadata.sealed && Boolean(metadata.live);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get the claim identifier for signing claim messages.
|
|
13
|
+
* This MUST match VaultActions.vue's getSerialNumber() logic:
|
|
14
|
+
* - ERC1155: use targetContract.serialNumber
|
|
15
|
+
* - ERC721a: use tokenId
|
|
16
|
+
* - Legacy: use tokenId
|
|
17
|
+
*/
|
|
18
|
+
export function getClaimIdentifier(metadata: {
|
|
19
|
+
ownershipInfo?: {
|
|
20
|
+
serialNumber?: string;
|
|
21
|
+
category?: string;
|
|
22
|
+
};
|
|
23
|
+
tokenId?: string;
|
|
24
|
+
targetContract?: {
|
|
25
|
+
serialNumber?: string;
|
|
26
|
+
collectionType?: string;
|
|
27
|
+
tokenId?: string;
|
|
28
|
+
};
|
|
29
|
+
}): string {
|
|
30
|
+
const { targetContract, ownershipInfo, tokenId } = metadata;
|
|
31
|
+
|
|
32
|
+
// If no targetContract, fallback to tokenId
|
|
33
|
+
if (!targetContract) {
|
|
34
|
+
return tokenId || '';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ERC1155: use serialNumber
|
|
38
|
+
if (
|
|
39
|
+
targetContract.collectionType === 'ERC1155' ||
|
|
40
|
+
ownershipInfo?.category === 'erc1155'
|
|
41
|
+
) {
|
|
42
|
+
return targetContract.serialNumber || tokenId || '';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ERC721a: use tokenId (NOT serialNumber!)
|
|
46
|
+
if (
|
|
47
|
+
targetContract.collectionType === 'ERC721a' ||
|
|
48
|
+
ownershipInfo?.category === 'erc721a'
|
|
49
|
+
) {
|
|
50
|
+
return tokenId || '';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Default: use targetContract.tokenId or tokenId
|
|
54
|
+
return targetContract.tokenId || tokenId || '';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function getHandlerContractAddress(chainId: number): string {
|
|
58
|
+
const config = getChainConfig(chainId);
|
|
59
|
+
if (!config.handlerContract) {
|
|
60
|
+
throw new Error(`No handler contract configured for chain ${chainId}`);
|
|
61
|
+
}
|
|
62
|
+
return config.handlerContract;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function getUnvaultingContractAddress(chainId: number): string {
|
|
66
|
+
const config = getChainConfig(chainId);
|
|
67
|
+
if (!config.unvaultingContract) {
|
|
68
|
+
throw new Error(`No unvaulting contract configured for chain ${chainId}`);
|
|
69
|
+
}
|
|
70
|
+
return config.unvaultingContract;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function getChainConfig(chainId: number | string): ChainConfig {
|
|
74
|
+
const config = SUPPORTED_CHAINS[chainId];
|
|
75
|
+
if (!config) {
|
|
76
|
+
const supportedList = Object.entries(SUPPORTED_CHAINS)
|
|
77
|
+
.map(([id, cfg]) => `${cfg.name} (${id})`)
|
|
78
|
+
.join(', ');
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Unsupported chain: ${chainId}. Supported chains: ${supportedList}`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return config;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function isEvmChain(chainId: number | string): boolean {
|
|
87
|
+
const config = SUPPORTED_CHAINS[chainId];
|
|
88
|
+
return config?.type === 'evm';
|
|
89
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const ETHEREUM_MAINNET_CHAIN_ID = 1;
|
|
2
|
+
export declare const POLYGON_MAINNET_CHAIN_ID = 137;
|
|
3
|
+
export declare const SOLANA_CHAIN_IDENTIFIER = "solana";
|
|
4
|
+
export type ChainType = 'evm' | 'solana';
|
|
5
|
+
export interface ChainConfig {
|
|
6
|
+
type: ChainType;
|
|
7
|
+
name: string;
|
|
8
|
+
handlerContract?: string;
|
|
9
|
+
unvaultingContract?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const SUPPORTED_CHAINS: Record<number | string, ChainConfig>;
|
|
12
|
+
export declare const HANDLER_CONTRACT_ADDRESS = "0x23859b51117dbFBcdEf5b757028B18d7759a4460";
|
|
13
|
+
export declare const UNVAULTING_DIAMOND_ADDRESS = "0x214C964bBd3640971E111d3a994CbB89b296a9ad";
|
|
14
|
+
export declare const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
15
|
+
export declare const EMBLEM_API_V2 = "https://v2.emblemvault.io";
|
|
16
|
+
export declare const EMBLEM_API_2 = "https://api2.emblemvault.io";
|
|
17
|
+
export declare const TORUS_SIGNER_API = "https://tor-us-signer-coval.vercel.app";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EmblemVaultClient, ProgressCallback, MintResult, ClaimResult, MetaData, SdkContext } from './types';
|
|
2
|
+
export declare function performMintEvm(ctx: SdkContext, client: EmblemVaultClient, tokenId: string, chainId: number, callback?: ProgressCallback): Promise<MintResult>;
|
|
3
|
+
export declare function performClaimEvm(ctx: SdkContext, client: EmblemVaultClient, tokenId: string, chainId: number, metadata: MetaData, claimIdentifier: string, vaultIsV2: boolean, needsOnChainUnvault: boolean, callback?: ProgressCallback): Promise<ClaimResult>;
|
|
4
|
+
export declare function deleteVaultEvm(client: EmblemVaultClient, tokenId: string, chainId: number, callback?: ProgressCallback): Promise<boolean>;
|
package/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BigNumber } from '@ethersproject/bignumber';
|
|
2
|
-
import { Collection, CuratedCollectionsResponse, MetaData, Ownership, Vault } from './types';
|
|
2
|
+
import type { Collection, CuratedCollectionsResponse, MetaData, Ownership, Vault, ProgressCallback, MintResult, ClaimResult, EmblemVaultClient } from './types';
|
|
3
3
|
declare class EmblemVaultSDK {
|
|
4
4
|
private apiKey;
|
|
5
5
|
private baseUrl;
|
|
@@ -20,7 +20,27 @@ declare class EmblemVaultSDK {
|
|
|
20
20
|
refreshOwnershipForAccount(account: string, callback?: any): Promise<Ownership[]>;
|
|
21
21
|
fetchMetadata(tokenId: string, callback?: any): Promise<MetaData>;
|
|
22
22
|
refreshBalance(tokenId: string, callback?: any): Promise<MetaData>;
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Fetch vaults of a specific type for an address.
|
|
25
|
+
* @param vaultType - The vault type: "vaulted", "unvaulted", or "created"
|
|
26
|
+
* @param address - The wallet address to fetch vaults for
|
|
27
|
+
* @param options - Optional pagination options
|
|
28
|
+
* @param options.page - Page number (1-indexed). If provided, returns paginated response.
|
|
29
|
+
* @param options.limit - Number of results per page (default: 100)
|
|
30
|
+
* @returns Array of vaults (unpaginated) or { data, pagination } object (paginated)
|
|
31
|
+
*/
|
|
32
|
+
fetchVaultsOfType(vaultType: string, address: string, options?: {
|
|
33
|
+
page?: number;
|
|
34
|
+
limit?: number;
|
|
35
|
+
}): Promise<any>;
|
|
36
|
+
/**
|
|
37
|
+
* Fetch all vaults of a specific type, automatically handling pagination.
|
|
38
|
+
* @param vaultType - The vault type: "vaulted", "unvaulted", or "created"
|
|
39
|
+
* @param address - The wallet address to fetch vaults for
|
|
40
|
+
* @param onProgress - Optional callback for progress updates (page, totalPages, total)
|
|
41
|
+
* @returns Array of all vaults
|
|
42
|
+
*/
|
|
43
|
+
fetchAllVaultsOfType(vaultType: string, address: string, onProgress?: (page: number, totalPages: number, total: number) => void): Promise<any[]>;
|
|
24
44
|
generateJumpReport(address: string, hideUnMintable?: boolean): Promise<unknown>;
|
|
25
45
|
generateMintReport(address: string, hideUnMintable?: boolean): Promise<unknown>;
|
|
26
46
|
generateMigrateReport(address: string, hideUnMintable?: boolean): Promise<unknown>;
|
|
@@ -45,6 +65,10 @@ declare class EmblemVaultSDK {
|
|
|
45
65
|
refreshLegacyOwnership(web3: any, address: string): Promise<void>;
|
|
46
66
|
checkLiveliness(tokenId: string, chainId?: number): Promise<any>;
|
|
47
67
|
checkLivelinessBulk(tokenIds: string[], chainId?: number): Promise<any[]>;
|
|
68
|
+
private getSdkContext;
|
|
69
|
+
performMintChainWithClient(client: EmblemVaultClient, tokenId: string, chainId?: number | 'solana', callback?: ProgressCallback): Promise<MintResult>;
|
|
70
|
+
performClaimChainWithClient(client: EmblemVaultClient, tokenId: string, chainId?: number | 'solana', callback?: ProgressCallback): Promise<ClaimResult>;
|
|
71
|
+
deleteVaultWithClient(client: EmblemVaultClient, tokenId: string, chainId?: number | 'solana', callback?: ProgressCallback): Promise<boolean>;
|
|
48
72
|
sweepVaultUsingPhrase(phrase: string, satsPerByte?: number, broadcast?: boolean): Promise<unknown>;
|
|
49
73
|
}
|
|
50
74
|
declare global {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function buildMintMessage(tokenId: string): string;
|
|
2
|
+
export declare function buildClaimMessage(identifier: string, isV2Vault: boolean): string;
|
|
3
|
+
export declare function buildUnvaultMessage(identifier: string): string;
|
|
4
|
+
export declare function buildDeleteMessage(tokenId: string): string;
|
package/types/types.d.ts
CHANGED
|
@@ -26,6 +26,14 @@ export type Collection = {
|
|
|
26
26
|
balanceCheckers: string[] | null;
|
|
27
27
|
tokenIdScheme: string | null;
|
|
28
28
|
generateVaultBody: Function;
|
|
29
|
+
/**
|
|
30
|
+
* Returns a template ready to send to the create vault API
|
|
31
|
+
*
|
|
32
|
+
* @param {FillCreateVaultTemplateArgs} args - Arguments to fill the template
|
|
33
|
+
* @param {_this: Collection} _this - The collection context
|
|
34
|
+
* @returns {Object} - Filled create vault template
|
|
35
|
+
*/
|
|
36
|
+
fillCreateVaultTemplate: (args: FillCreateVaultTemplateArgs, _this: Collection) => Object;
|
|
29
37
|
generateCreateTemplate: Function;
|
|
30
38
|
};
|
|
31
39
|
export interface MetaData {
|
|
@@ -133,3 +141,82 @@ export type Ownership = {
|
|
|
133
141
|
network: string;
|
|
134
142
|
};
|
|
135
143
|
export type CuratedCollectionsResponse = Collection[];
|
|
144
|
+
export type ChainIdentifier = number | 'solana';
|
|
145
|
+
export type ProgressCallback = (message: string, data?: unknown) => void;
|
|
146
|
+
export interface MintResult {
|
|
147
|
+
txHash: string;
|
|
148
|
+
tokenId: string;
|
|
149
|
+
chainId: ChainIdentifier;
|
|
150
|
+
}
|
|
151
|
+
export interface ClaimResult {
|
|
152
|
+
phrase?: string;
|
|
153
|
+
privateKey?: string;
|
|
154
|
+
}
|
|
155
|
+
export interface RemoteMintSignature {
|
|
156
|
+
_nftAddress: string;
|
|
157
|
+
_price: {
|
|
158
|
+
hex: string;
|
|
159
|
+
} | string | number;
|
|
160
|
+
_to: string;
|
|
161
|
+
_tokenId: {
|
|
162
|
+
hex: string;
|
|
163
|
+
} | string | number;
|
|
164
|
+
_nonce: {
|
|
165
|
+
hex: string;
|
|
166
|
+
} | string | number;
|
|
167
|
+
_signature: string;
|
|
168
|
+
serialNumber: string;
|
|
169
|
+
error?: string;
|
|
170
|
+
}
|
|
171
|
+
export interface RemoteUnvaultSignature {
|
|
172
|
+
success: boolean;
|
|
173
|
+
_nftAddress: string;
|
|
174
|
+
_tokenId: {
|
|
175
|
+
hex: string;
|
|
176
|
+
} | string | number;
|
|
177
|
+
_nonce: {
|
|
178
|
+
hex: string;
|
|
179
|
+
} | string | number;
|
|
180
|
+
_price: {
|
|
181
|
+
hex: string;
|
|
182
|
+
} | string | number;
|
|
183
|
+
_timestamp: {
|
|
184
|
+
hex: string;
|
|
185
|
+
} | string | number;
|
|
186
|
+
_signature: string;
|
|
187
|
+
msg?: string;
|
|
188
|
+
err?: string;
|
|
189
|
+
}
|
|
190
|
+
export interface EvmSigner {
|
|
191
|
+
getAddress(): Promise<string>;
|
|
192
|
+
signMessage(message: string | Uint8Array): Promise<string>;
|
|
193
|
+
sendTransaction(tx: unknown): Promise<{
|
|
194
|
+
hash: string;
|
|
195
|
+
wait(): Promise<unknown>;
|
|
196
|
+
}>;
|
|
197
|
+
setChainId?(chainId: number): void;
|
|
198
|
+
}
|
|
199
|
+
export interface EmblemVaultClient {
|
|
200
|
+
toEthersWallet(provider?: unknown): Promise<EvmSigner>;
|
|
201
|
+
}
|
|
202
|
+
export interface SdkContext {
|
|
203
|
+
apiKey: string;
|
|
204
|
+
baseUrl: string;
|
|
205
|
+
v3Url: string;
|
|
206
|
+
sigUrl: string;
|
|
207
|
+
fetchMetadata: (tokenId: string, callback?: ProgressCallback) => Promise<MetaData>;
|
|
208
|
+
requestRemoteKey: (tokenId: string, jwt: unknown, callback?: ProgressCallback) => Promise<unknown>;
|
|
209
|
+
decryptVaultKeys: (tokenId: string, dkeys: unknown, callback?: ProgressCallback) => Promise<ClaimResult>;
|
|
210
|
+
}
|
|
211
|
+
export interface FillCreateVaultTemplateArgs {
|
|
212
|
+
fromAddress: string;
|
|
213
|
+
toAddress: string;
|
|
214
|
+
targetAsset: {
|
|
215
|
+
name: string;
|
|
216
|
+
image: string;
|
|
217
|
+
description?: string;
|
|
218
|
+
ownedImage?: string;
|
|
219
|
+
projectName?: string;
|
|
220
|
+
};
|
|
221
|
+
chainId: number;
|
|
222
|
+
}
|
package/types/utils.d.ts
CHANGED
|
@@ -40,4 +40,5 @@ interface SatsConnectAddress {
|
|
|
40
40
|
}
|
|
41
41
|
export declare function getSatsConnectAddress(): Promise<SatsConnectAddress>;
|
|
42
42
|
export declare function signPSBT(psbtBase64: any, paymentAddress: any, indexes: number[], broadcast?: boolean): Promise<unknown>;
|
|
43
|
+
export declare function parseBigIntValue(value: unknown): bigint;
|
|
43
44
|
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ChainConfig } from "./constants";
|
|
2
|
+
export declare function isV2Vault(metadata: {
|
|
3
|
+
targetContract?: {
|
|
4
|
+
name?: string;
|
|
5
|
+
};
|
|
6
|
+
}): boolean;
|
|
7
|
+
export declare function requiresOnChainUnvault(metadata: {
|
|
8
|
+
status?: string;
|
|
9
|
+
sealed?: boolean;
|
|
10
|
+
live?: boolean;
|
|
11
|
+
}): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Get the claim identifier for signing claim messages.
|
|
14
|
+
* This MUST match VaultActions.vue's getSerialNumber() logic:
|
|
15
|
+
* - ERC1155: use targetContract.serialNumber
|
|
16
|
+
* - ERC721a: use tokenId
|
|
17
|
+
* - Legacy: use tokenId
|
|
18
|
+
*/
|
|
19
|
+
export declare function getClaimIdentifier(metadata: {
|
|
20
|
+
ownershipInfo?: {
|
|
21
|
+
serialNumber?: string;
|
|
22
|
+
category?: string;
|
|
23
|
+
};
|
|
24
|
+
tokenId?: string;
|
|
25
|
+
targetContract?: {
|
|
26
|
+
serialNumber?: string;
|
|
27
|
+
collectionType?: string;
|
|
28
|
+
tokenId?: string;
|
|
29
|
+
};
|
|
30
|
+
}): string;
|
|
31
|
+
export declare function getHandlerContractAddress(chainId: number): string;
|
|
32
|
+
export declare function getUnvaultingContractAddress(chainId: number): string;
|
|
33
|
+
export declare function getChainConfig(chainId: number | string): ChainConfig;
|
|
34
|
+
export declare function isEvmChain(chainId: number | string): boolean;
|