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
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Supported Chains
|
|
4
|
+
// ============================================================================
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TORUS_SIGNER_API = exports.EMBLEM_API_2 = exports.EMBLEM_API_V2 = exports.ZERO_ADDRESS = exports.UNVAULTING_DIAMOND_ADDRESS = exports.HANDLER_CONTRACT_ADDRESS = exports.SUPPORTED_CHAINS = exports.SOLANA_CHAIN_IDENTIFIER = exports.POLYGON_MAINNET_CHAIN_ID = exports.ETHEREUM_MAINNET_CHAIN_ID = void 0;
|
|
7
|
+
exports.ETHEREUM_MAINNET_CHAIN_ID = 1;
|
|
8
|
+
exports.POLYGON_MAINNET_CHAIN_ID = 137;
|
|
9
|
+
exports.SOLANA_CHAIN_IDENTIFIER = 'solana';
|
|
10
|
+
exports.SUPPORTED_CHAINS = {
|
|
11
|
+
[exports.ETHEREUM_MAINNET_CHAIN_ID]: {
|
|
12
|
+
type: 'evm',
|
|
13
|
+
name: 'Ethereum Mainnet',
|
|
14
|
+
handlerContract: '0x23859b51117dbFBcdEf5b757028B18d7759a4460',
|
|
15
|
+
unvaultingContract: '0x214C964bBd3640971E111d3a994CbB89b296a9ad',
|
|
16
|
+
},
|
|
17
|
+
[exports.POLYGON_MAINNET_CHAIN_ID]: {
|
|
18
|
+
type: 'evm',
|
|
19
|
+
name: 'Polygon Mainnet',
|
|
20
|
+
handlerContract: '0x23859b51117dbFBcdEf5b757028B18d7759a4460',
|
|
21
|
+
unvaultingContract: '0x214C964bBd3640971E111d3a994CbB89b296a9ad',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Contract Addresses (default to Ethereum mainnet)
|
|
26
|
+
// ============================================================================
|
|
27
|
+
exports.HANDLER_CONTRACT_ADDRESS = '0x23859b51117dbFBcdEf5b757028B18d7759a4460';
|
|
28
|
+
exports.UNVAULTING_DIAMOND_ADDRESS = '0x214C964bBd3640971E111d3a994CbB89b296a9ad';
|
|
29
|
+
exports.ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// API Endpoints
|
|
32
|
+
// ============================================================================
|
|
33
|
+
exports.EMBLEM_API_V2 = 'https://v2.emblemvault.io';
|
|
34
|
+
exports.EMBLEM_API_2 = 'https://api2.emblemvault.io';
|
|
35
|
+
exports.TORUS_SIGNER_API = 'https://tor-us-signer-coval.vercel.app';
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.performMintEvm = performMintEvm;
|
|
46
|
+
exports.performClaimEvm = performClaimEvm;
|
|
47
|
+
exports.deleteVaultEvm = deleteVaultEvm;
|
|
48
|
+
const constants_1 = require("./constants");
|
|
49
|
+
const signing_messages_1 = require("./signing-messages");
|
|
50
|
+
const vault_utils_1 = require("./vault-utils");
|
|
51
|
+
const utils_1 = require("./utils");
|
|
52
|
+
const EVM_RPC_URLS = {
|
|
53
|
+
1: 'https://eth.llamarpc.com',
|
|
54
|
+
137: 'https://polygon-rpc.com',
|
|
55
|
+
};
|
|
56
|
+
function getEvmRpcUrl(chainId) {
|
|
57
|
+
return EVM_RPC_URLS[chainId] || EVM_RPC_URLS[1];
|
|
58
|
+
}
|
|
59
|
+
function performMintEvm(ctx, client, tokenId, chainId, callback) {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
var _a;
|
|
62
|
+
callback === null || callback === void 0 ? void 0 : callback('Initializing EVM signer...');
|
|
63
|
+
const { ethers } = yield Promise.resolve().then(() => __importStar(require('ethers')));
|
|
64
|
+
const provider = new ethers.providers.JsonRpcProvider(getEvmRpcUrl(chainId));
|
|
65
|
+
const wallet = yield client.toEthersWallet(provider);
|
|
66
|
+
(_a = wallet.setChainId) === null || _a === void 0 ? void 0 : _a.call(wallet, chainId);
|
|
67
|
+
callback === null || callback === void 0 ? void 0 : callback('Signing mint request...');
|
|
68
|
+
const mintMessage = (0, signing_messages_1.buildMintMessage)(tokenId);
|
|
69
|
+
const mintRequestSig = yield wallet.signMessage(mintMessage);
|
|
70
|
+
callback === null || callback === void 0 ? void 0 : callback('Getting remote mint signature...');
|
|
71
|
+
const remoteMintSig = yield requestRemoteMintSignature(ctx, tokenId, mintRequestSig, chainId);
|
|
72
|
+
callback === null || callback === void 0 ? void 0 : callback('Submitting mint transaction...');
|
|
73
|
+
const txHash = yield submitMintTransaction(wallet, remoteMintSig, chainId, callback);
|
|
74
|
+
callback === null || callback === void 0 ? void 0 : callback('Mint complete!', { txHash });
|
|
75
|
+
return { txHash, tokenId, chainId };
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function performClaimEvm(ctx, client, tokenId, chainId, metadata, claimIdentifier, vaultIsV2, needsOnChainUnvault, callback) {
|
|
79
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
+
var _a, _b;
|
|
81
|
+
callback === null || callback === void 0 ? void 0 : callback('Initializing EVM signer...');
|
|
82
|
+
const { ethers } = yield Promise.resolve().then(() => __importStar(require('ethers')));
|
|
83
|
+
const provider = new ethers.providers.JsonRpcProvider(getEvmRpcUrl(chainId));
|
|
84
|
+
const wallet = yield client.toEthersWallet(provider);
|
|
85
|
+
(_a = wallet.setChainId) === null || _a === void 0 ? void 0 : _a.call(wallet, chainId);
|
|
86
|
+
// Determine if vault needs on-chain claim/unvault before getting keys
|
|
87
|
+
// For minted vaults (live=true, status=unclaimed), we must claim on-chain first
|
|
88
|
+
const isMinted = metadata.live === true || metadata.status === 'unclaimed';
|
|
89
|
+
const isAlreadyClaimed = metadata.status === 'claimed' || Boolean(metadata.claimedBy);
|
|
90
|
+
if (isMinted && !isAlreadyClaimed) {
|
|
91
|
+
if (needsOnChainUnvault) {
|
|
92
|
+
// V2 vault: use unvaultWithSignedPrice
|
|
93
|
+
yield performOnChainUnvault(ctx, wallet, tokenId, claimIdentifier, metadata.collectionAddress, chainId, callback);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Non-V2 vault: use handler's claim function
|
|
97
|
+
const targetContractAddress = ((_b = metadata.targetContract) === null || _b === void 0 ? void 0 : _b[chainId]) || metadata.collectionAddress;
|
|
98
|
+
if (targetContractAddress) {
|
|
99
|
+
callback === null || callback === void 0 ? void 0 : callback('Performing on-chain claim...');
|
|
100
|
+
yield performLegacyClaim(wallet, targetContractAddress, claimIdentifier, chainId, callback);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
callback === null || callback === void 0 ? void 0 : callback('Signing claim message...');
|
|
105
|
+
const claimMessage = (0, signing_messages_1.buildClaimMessage)(claimIdentifier, vaultIsV2);
|
|
106
|
+
const signature = yield wallet.signMessage(claimMessage);
|
|
107
|
+
callback === null || callback === void 0 ? void 0 : callback('Requesting claim token...');
|
|
108
|
+
const jwt = yield requestClaimToken(tokenId, signature, chainId);
|
|
109
|
+
callback === null || callback === void 0 ? void 0 : callback('Requesting remote key...');
|
|
110
|
+
const decryptionKeys = yield ctx.requestRemoteKey(tokenId, jwt, callback);
|
|
111
|
+
if (!decryptionKeys) {
|
|
112
|
+
throw new Error('Failed to get decryption key');
|
|
113
|
+
}
|
|
114
|
+
callback === null || callback === void 0 ? void 0 : callback('Decrypting vault keys...');
|
|
115
|
+
return yield ctx.decryptVaultKeys(tokenId, decryptionKeys, callback);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function deleteVaultEvm(client, tokenId, chainId, callback) {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
var _a;
|
|
121
|
+
callback === null || callback === void 0 ? void 0 : callback('Initializing EVM signer...');
|
|
122
|
+
const wallet = yield client.toEthersWallet(null);
|
|
123
|
+
(_a = wallet.setChainId) === null || _a === void 0 ? void 0 : _a.call(wallet, chainId);
|
|
124
|
+
callback === null || callback === void 0 ? void 0 : callback('Signing delete message...');
|
|
125
|
+
const deleteMessage = (0, signing_messages_1.buildDeleteMessage)(tokenId);
|
|
126
|
+
const signature = yield wallet.signMessage(deleteMessage);
|
|
127
|
+
callback === null || callback === void 0 ? void 0 : callback('Deleting vault...');
|
|
128
|
+
const response = yield fetch(`${constants_1.EMBLEM_API_2}/v2/delete`, {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: {
|
|
131
|
+
'Content-Type': 'application/json',
|
|
132
|
+
service: 'evmetadata',
|
|
133
|
+
},
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
tokenId,
|
|
136
|
+
signature,
|
|
137
|
+
chainId: chainId.toString(),
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
if (!response.ok) {
|
|
141
|
+
const errorData = yield response.json().catch(() => ({}));
|
|
142
|
+
throw new Error(errorData.message || 'Failed to delete vault');
|
|
143
|
+
}
|
|
144
|
+
callback === null || callback === void 0 ? void 0 : callback('Vault deleted successfully');
|
|
145
|
+
return true;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function requestRemoteMintSignature(ctx, tokenId, signature, chainId) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const url = `${ctx.baseUrl}/mint-curated`;
|
|
151
|
+
const remoteMintResponse = yield (0, utils_1.fetchData)(url, ctx.apiKey, 'POST', {
|
|
152
|
+
method: 'buyWithSignedPrice',
|
|
153
|
+
tokenId,
|
|
154
|
+
signature,
|
|
155
|
+
chainId: chainId.toString(),
|
|
156
|
+
});
|
|
157
|
+
// Handle both 'error' and 'err' fields (API inconsistency)
|
|
158
|
+
const errorMsg = remoteMintResponse.error || remoteMintResponse.err;
|
|
159
|
+
if (errorMsg) {
|
|
160
|
+
const message = typeof errorMsg === 'string'
|
|
161
|
+
? errorMsg
|
|
162
|
+
: errorMsg.msg || errorMsg.message || JSON.stringify(errorMsg);
|
|
163
|
+
throw new Error(message);
|
|
164
|
+
}
|
|
165
|
+
return remoteMintResponse;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function submitMintTransaction(wallet, remoteMintSig, chainId, callback) {
|
|
169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
const { ethers } = yield Promise.resolve().then(() => __importStar(require('ethers')));
|
|
171
|
+
const handlerAddress = (0, vault_utils_1.getHandlerContractAddress)(chainId);
|
|
172
|
+
const priceBigInt = (0, utils_1.parseBigIntValue)(remoteMintSig._price);
|
|
173
|
+
const iface = new ethers.utils.Interface([
|
|
174
|
+
'function buyWithSignedPrice(address _nftAddress, address _payment, uint256 _price, address _to, uint256 _tokenId, uint256 _nonce, bytes _signature, bytes serialNumber, uint256 _amount) payable'
|
|
175
|
+
]);
|
|
176
|
+
const data = iface.encodeFunctionData('buyWithSignedPrice', [
|
|
177
|
+
remoteMintSig._nftAddress,
|
|
178
|
+
constants_1.ZERO_ADDRESS,
|
|
179
|
+
priceBigInt,
|
|
180
|
+
remoteMintSig._to,
|
|
181
|
+
(0, utils_1.parseBigIntValue)(remoteMintSig._tokenId),
|
|
182
|
+
(0, utils_1.parseBigIntValue)(remoteMintSig._nonce),
|
|
183
|
+
remoteMintSig._signature,
|
|
184
|
+
remoteMintSig.serialNumber,
|
|
185
|
+
BigInt(1),
|
|
186
|
+
]);
|
|
187
|
+
const tx = yield wallet.sendTransaction({
|
|
188
|
+
to: handlerAddress,
|
|
189
|
+
data,
|
|
190
|
+
value: priceBigInt,
|
|
191
|
+
});
|
|
192
|
+
callback === null || callback === void 0 ? void 0 : callback('Waiting for confirmation...', { txHash: tx.hash });
|
|
193
|
+
yield tx.wait();
|
|
194
|
+
return tx.hash;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
function performOnChainUnvault(ctx, wallet, tokenId, claimIdentifier, nftAddress, chainId, callback) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
+
callback === null || callback === void 0 ? void 0 : callback('Signing unvault request...');
|
|
200
|
+
// Sign with tokenId to match server expectation (server verifies "Unvault: " + req.body.tokenId)
|
|
201
|
+
const unvaultMessage = (0, signing_messages_1.buildUnvaultMessage)(tokenId);
|
|
202
|
+
const unvaultSignature = yield wallet.signMessage(unvaultMessage);
|
|
203
|
+
callback === null || callback === void 0 ? void 0 : callback('Requesting remote unvault signature...');
|
|
204
|
+
const remoteUnvaultSig = yield requestRemoteUnvaultSignature(ctx, tokenId, unvaultSignature, chainId);
|
|
205
|
+
callback === null || callback === void 0 ? void 0 : callback('Submitting on-chain unvault transaction...');
|
|
206
|
+
yield submitUnvaultTransaction(wallet, remoteUnvaultSig, nftAddress, chainId, callback);
|
|
207
|
+
callback === null || callback === void 0 ? void 0 : callback('On-chain unvault complete, retrieving keys...');
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Perform legacy claim by calling the handler contract's claim function
|
|
212
|
+
* This is for non-V2 vaults that don't use signed price unvaulting
|
|
213
|
+
*/
|
|
214
|
+
function performLegacyClaim(wallet, targetContractAddress, tokenId, chainId, callback) {
|
|
215
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
216
|
+
const { ethers } = yield Promise.resolve().then(() => __importStar(require('ethers')));
|
|
217
|
+
// Handler contract ABI for claim function
|
|
218
|
+
const HANDLER_CLAIM_ABI = [
|
|
219
|
+
'function claim(address _nftAddress, uint256 _tokenId) external'
|
|
220
|
+
];
|
|
221
|
+
const handlerAddress = (0, vault_utils_1.getHandlerContractAddress)(chainId);
|
|
222
|
+
const iface = new ethers.utils.Interface(HANDLER_CLAIM_ABI);
|
|
223
|
+
const data = iface.encodeFunctionData('claim', [
|
|
224
|
+
targetContractAddress,
|
|
225
|
+
BigInt(tokenId),
|
|
226
|
+
]);
|
|
227
|
+
callback === null || callback === void 0 ? void 0 : callback('Submitting claim transaction...');
|
|
228
|
+
const tx = yield wallet.sendTransaction({
|
|
229
|
+
to: handlerAddress,
|
|
230
|
+
data,
|
|
231
|
+
});
|
|
232
|
+
callback === null || callback === void 0 ? void 0 : callback('Waiting for claim confirmation...', { txHash: tx.hash });
|
|
233
|
+
yield tx.wait();
|
|
234
|
+
callback === null || callback === void 0 ? void 0 : callback('On-chain claim complete!');
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function requestRemoteUnvaultSignature(ctx, tokenId, signature, chainId) {
|
|
238
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
239
|
+
const response = yield fetch(`${ctx.baseUrl}/unvault-curated`, {
|
|
240
|
+
method: 'POST',
|
|
241
|
+
headers: { 'Content-Type': 'application/json' },
|
|
242
|
+
body: JSON.stringify({
|
|
243
|
+
method: 'unvaultWithSignedPrice',
|
|
244
|
+
tokenId,
|
|
245
|
+
signature,
|
|
246
|
+
chainId: chainId.toString(),
|
|
247
|
+
}),
|
|
248
|
+
});
|
|
249
|
+
const remoteUnvaultSig = yield response.json();
|
|
250
|
+
if (!(remoteUnvaultSig === null || remoteUnvaultSig === void 0 ? void 0 : remoteUnvaultSig.success)) {
|
|
251
|
+
throw new Error((remoteUnvaultSig === null || remoteUnvaultSig === void 0 ? void 0 : remoteUnvaultSig.msg) || (remoteUnvaultSig === null || remoteUnvaultSig === void 0 ? void 0 : remoteUnvaultSig.err) || 'Failed to get remote unvault signature');
|
|
252
|
+
}
|
|
253
|
+
return remoteUnvaultSig;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
function submitUnvaultTransaction(wallet, remoteUnvaultSig, nftAddress, chainId, callback) {
|
|
257
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
258
|
+
const { ethers } = yield Promise.resolve().then(() => __importStar(require('ethers')));
|
|
259
|
+
const unvaultingAddress = (0, vault_utils_1.getUnvaultingContractAddress)(chainId);
|
|
260
|
+
const nftAddressToUse = nftAddress || remoteUnvaultSig._nftAddress;
|
|
261
|
+
const tokenId = (0, utils_1.parseBigIntValue)(remoteUnvaultSig._tokenId);
|
|
262
|
+
const nonce = (0, utils_1.parseBigIntValue)(remoteUnvaultSig._nonce);
|
|
263
|
+
const price = (0, utils_1.parseBigIntValue)(remoteUnvaultSig._price);
|
|
264
|
+
const timestamp = (0, utils_1.parseBigIntValue)(remoteUnvaultSig._timestamp);
|
|
265
|
+
const iface = new ethers.utils.Interface([
|
|
266
|
+
'function unvaultWithSignedPrice(address _nftAddress, uint256 _tokenId, uint256 _nonce, address _payment, uint256 _price, bytes _signature, uint256 _timestamp) payable'
|
|
267
|
+
]);
|
|
268
|
+
const data = iface.encodeFunctionData('unvaultWithSignedPrice', [
|
|
269
|
+
nftAddressToUse,
|
|
270
|
+
tokenId,
|
|
271
|
+
nonce,
|
|
272
|
+
constants_1.ZERO_ADDRESS,
|
|
273
|
+
price,
|
|
274
|
+
remoteUnvaultSig._signature,
|
|
275
|
+
timestamp,
|
|
276
|
+
]);
|
|
277
|
+
const tx = yield wallet.sendTransaction({
|
|
278
|
+
to: unvaultingAddress,
|
|
279
|
+
data,
|
|
280
|
+
value: price,
|
|
281
|
+
});
|
|
282
|
+
callback === null || callback === void 0 ? void 0 : callback('Waiting for unvault confirmation...', { txHash: tx.hash });
|
|
283
|
+
yield tx.wait();
|
|
284
|
+
return tx.hash;
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
function requestClaimToken(tokenId, signature, chainId) {
|
|
288
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
289
|
+
const response = yield fetch(`${constants_1.TORUS_SIGNER_API}/sign`, {
|
|
290
|
+
method: 'POST',
|
|
291
|
+
headers: {
|
|
292
|
+
'Content-Type': 'application/json',
|
|
293
|
+
chainid: chainId.toString(),
|
|
294
|
+
},
|
|
295
|
+
body: JSON.stringify({ signature, tokenId }),
|
|
296
|
+
});
|
|
297
|
+
const jwt = yield response.json();
|
|
298
|
+
if (!jwt || jwt.success === false) {
|
|
299
|
+
throw new Error((jwt === null || jwt === void 0 ? void 0 : jwt.debug) ? `Claim failed: ${JSON.stringify(jwt.debug)}` : 'Failed to get claim token');
|
|
300
|
+
}
|
|
301
|
+
return jwt;
|
|
302
|
+
});
|
|
303
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -45,7 +45,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
45
45
|
const bignumber_1 = require("@ethersproject/bignumber");
|
|
46
46
|
const utils_1 = require("./utils");
|
|
47
47
|
const derive_1 = require("./derive");
|
|
48
|
-
const
|
|
48
|
+
const constants_1 = require("./constants");
|
|
49
|
+
const vault_utils_1 = require("./vault-utils");
|
|
50
|
+
const evm_operations_1 = require("./evm-operations");
|
|
51
|
+
const SDK_VERSION = '2.9.2';
|
|
49
52
|
class EmblemVaultSDK {
|
|
50
53
|
constructor(apiKey, baseUrl, v3Url, sigUrl) {
|
|
51
54
|
this.apiKey = apiKey;
|
|
@@ -107,7 +110,7 @@ class EmblemVaultSDK {
|
|
|
107
110
|
item[key] = template[key];
|
|
108
111
|
});
|
|
109
112
|
// Return a new object that combines the properties of the item and the template
|
|
110
|
-
|
|
113
|
+
return Object.assign(Object.assign({}, item), template);
|
|
111
114
|
return item;
|
|
112
115
|
});
|
|
113
116
|
return data;
|
|
@@ -129,8 +132,14 @@ class EmblemVaultSDK {
|
|
|
129
132
|
callback(`creating Vault for user`, template.toAddress);
|
|
130
133
|
}
|
|
131
134
|
let vaultCreationResponse = yield (0, utils_1.fetchData)(url, this.apiKey, 'POST', template);
|
|
135
|
+
if (vaultCreationResponse === null || vaultCreationResponse === void 0 ? void 0 : vaultCreationResponse.err) {
|
|
136
|
+
if (callback)
|
|
137
|
+
callback(`error creating Vault: ${vaultCreationResponse.msg}`);
|
|
138
|
+
return vaultCreationResponse;
|
|
139
|
+
}
|
|
140
|
+
const { tokenId } = vaultCreationResponse.data;
|
|
132
141
|
if (callback) {
|
|
133
|
-
callback(`created Vault tokenId
|
|
142
|
+
callback(`created Vault ${tokenId}`);
|
|
134
143
|
}
|
|
135
144
|
return vaultCreationResponse.data;
|
|
136
145
|
});
|
|
@@ -185,15 +194,65 @@ class EmblemVaultSDK {
|
|
|
185
194
|
return (balance === null || balance === void 0 ? void 0 : balance.balances) || [];
|
|
186
195
|
});
|
|
187
196
|
}
|
|
188
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Fetch vaults of a specific type for an address.
|
|
199
|
+
* @param vaultType - The vault type: "vaulted", "unvaulted", or "created"
|
|
200
|
+
* @param address - The wallet address to fetch vaults for
|
|
201
|
+
* @param options - Optional pagination options
|
|
202
|
+
* @param options.page - Page number (1-indexed). If provided, returns paginated response.
|
|
203
|
+
* @param options.limit - Number of results per page (default: 100)
|
|
204
|
+
* @returns Array of vaults (unpaginated) or { data, pagination } object (paginated)
|
|
205
|
+
*/
|
|
206
|
+
fetchVaultsOfType(vaultType, address, options) {
|
|
189
207
|
return __awaiter(this, void 0, void 0, function* () {
|
|
190
208
|
(0, utils_1.genericGuard)(vaultType, "string", "vaultType");
|
|
191
209
|
(0, utils_1.genericGuard)(address, "string", "address");
|
|
192
210
|
let url = `${this.baseUrl}/myvaults/${address}?vaultType=${vaultType}`;
|
|
211
|
+
// Add pagination params if provided
|
|
212
|
+
if ((options === null || options === void 0 ? void 0 : options.page) !== undefined || (options === null || options === void 0 ? void 0 : options.limit) !== undefined) {
|
|
213
|
+
if (options.page !== undefined)
|
|
214
|
+
url += `&page=${options.page}`;
|
|
215
|
+
if (options.limit !== undefined)
|
|
216
|
+
url += `&limit=${options.limit}`;
|
|
217
|
+
}
|
|
193
218
|
let vaults = yield (0, utils_1.fetchData)(url, this.apiKey);
|
|
194
219
|
return vaults;
|
|
195
220
|
});
|
|
196
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Fetch all vaults of a specific type, automatically handling pagination.
|
|
224
|
+
* @param vaultType - The vault type: "vaulted", "unvaulted", or "created"
|
|
225
|
+
* @param address - The wallet address to fetch vaults for
|
|
226
|
+
* @param onProgress - Optional callback for progress updates (page, totalPages, total)
|
|
227
|
+
* @returns Array of all vaults
|
|
228
|
+
*/
|
|
229
|
+
fetchAllVaultsOfType(vaultType, address, onProgress) {
|
|
230
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
231
|
+
(0, utils_1.genericGuard)(vaultType, "string", "vaultType");
|
|
232
|
+
(0, utils_1.genericGuard)(address, "string", "address");
|
|
233
|
+
const allVaults = [];
|
|
234
|
+
let page = 1;
|
|
235
|
+
let totalPages = 1;
|
|
236
|
+
const limit = 100;
|
|
237
|
+
while (page <= totalPages) {
|
|
238
|
+
const result = yield this.fetchVaultsOfType(vaultType, address, { page, limit });
|
|
239
|
+
if (result.pagination) {
|
|
240
|
+
// Paginated response
|
|
241
|
+
allVaults.push(...result.data);
|
|
242
|
+
totalPages = result.pagination.totalPages;
|
|
243
|
+
if (onProgress) {
|
|
244
|
+
onProgress(page, totalPages, result.pagination.total);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// Legacy non-paginated response (shouldn't happen with updated API)
|
|
249
|
+
return Array.isArray(result) ? result : [];
|
|
250
|
+
}
|
|
251
|
+
page++;
|
|
252
|
+
}
|
|
253
|
+
return allVaults;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
197
256
|
generateJumpReport(address_1) {
|
|
198
257
|
return __awaiter(this, arguments, void 0, function* (address, hideUnMintable = false) {
|
|
199
258
|
let vaultType = "unclaimed";
|
|
@@ -581,6 +640,50 @@ class EmblemVaultSDK {
|
|
|
581
640
|
return results;
|
|
582
641
|
});
|
|
583
642
|
}
|
|
643
|
+
// ========================================================================
|
|
644
|
+
// Remote Signer Methods (EmblemVaultClient) - Multi-Chain Support
|
|
645
|
+
// ========================================================================
|
|
646
|
+
getSdkContext() {
|
|
647
|
+
return {
|
|
648
|
+
apiKey: this.apiKey,
|
|
649
|
+
baseUrl: this.baseUrl,
|
|
650
|
+
v3Url: this.v3Url,
|
|
651
|
+
sigUrl: this.sigUrl,
|
|
652
|
+
fetchMetadata: this.fetchMetadata.bind(this),
|
|
653
|
+
requestRemoteKey: this.requestRemoteKey.bind(this),
|
|
654
|
+
decryptVaultKeys: this.decryptVaultKeys.bind(this),
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
performMintChainWithClient(client_1, tokenId_1) {
|
|
658
|
+
return __awaiter(this, arguments, void 0, function* (client, tokenId, chainId = constants_1.ETHEREUM_MAINNET_CHAIN_ID, callback) {
|
|
659
|
+
(0, utils_1.genericGuard)(tokenId, "string", "tokenId");
|
|
660
|
+
(0, vault_utils_1.getChainConfig)(chainId);
|
|
661
|
+
return (0, evm_operations_1.performMintEvm)(this.getSdkContext(), client, tokenId, chainId, callback);
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
performClaimChainWithClient(client_1, tokenId_1) {
|
|
665
|
+
return __awaiter(this, arguments, void 0, function* (client, tokenId, chainId = constants_1.ETHEREUM_MAINNET_CHAIN_ID, callback) {
|
|
666
|
+
var _a, _b;
|
|
667
|
+
(0, utils_1.genericGuard)(tokenId, "string", "tokenId");
|
|
668
|
+
(0, vault_utils_1.getChainConfig)(chainId);
|
|
669
|
+
callback === null || callback === void 0 ? void 0 : callback('Fetching vault metadata...');
|
|
670
|
+
const metadata = yield this.fetchMetadata(tokenId, callback);
|
|
671
|
+
const claimIdentifier = (0, vault_utils_1.getClaimIdentifier)(metadata);
|
|
672
|
+
// Check if this is a V2 vault by checking the deployment type (matches VaultActions.vue logic)
|
|
673
|
+
// metadata[chainId]?.type?.endsWith('V2') indicates a diamond/V2 contract
|
|
674
|
+
const deploymentInfo = metadata === null || metadata === void 0 ? void 0 : metadata[chainId];
|
|
675
|
+
const vaultIsV2 = Boolean((_b = (_a = deploymentInfo === null || deploymentInfo === void 0 ? void 0 : deploymentInfo.type) === null || _a === void 0 ? void 0 : _a.endsWith) === null || _b === void 0 ? void 0 : _b.call(_a, 'V2'));
|
|
676
|
+
const needsOnChainUnvault = (0, vault_utils_1.requiresOnChainUnvault)(metadata) && vaultIsV2;
|
|
677
|
+
return (0, evm_operations_1.performClaimEvm)(this.getSdkContext(), client, tokenId, chainId, metadata, claimIdentifier, vaultIsV2, needsOnChainUnvault, callback);
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
deleteVaultWithClient(client_1, tokenId_1) {
|
|
681
|
+
return __awaiter(this, arguments, void 0, function* (client, tokenId, chainId = constants_1.ETHEREUM_MAINNET_CHAIN_ID, callback) {
|
|
682
|
+
(0, utils_1.genericGuard)(tokenId, "string", "tokenId");
|
|
683
|
+
(0, vault_utils_1.getChainConfig)(chainId);
|
|
684
|
+
return (0, evm_operations_1.deleteVaultEvm)(client, tokenId, chainId, callback);
|
|
685
|
+
});
|
|
686
|
+
}
|
|
584
687
|
// BTC
|
|
585
688
|
sweepVaultUsingPhrase(phrase_1) {
|
|
586
689
|
return __awaiter(this, arguments, void 0, function* (phrase, satsPerByte = 20, broadcast = false) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildMintMessage = buildMintMessage;
|
|
4
|
+
exports.buildClaimMessage = buildClaimMessage;
|
|
5
|
+
exports.buildUnvaultMessage = buildUnvaultMessage;
|
|
6
|
+
exports.buildDeleteMessage = buildDeleteMessage;
|
|
7
|
+
function buildMintMessage(tokenId) {
|
|
8
|
+
return `Curated Minting: ${tokenId}`;
|
|
9
|
+
}
|
|
10
|
+
function buildClaimMessage(identifier, isV2Vault) {
|
|
11
|
+
const prefix = isV2Vault ? 'Unvault' : 'Claim';
|
|
12
|
+
return `${prefix}: ${identifier}`;
|
|
13
|
+
}
|
|
14
|
+
function buildUnvaultMessage(identifier) {
|
|
15
|
+
return `Unvault: ${identifier}`;
|
|
16
|
+
}
|
|
17
|
+
function buildDeleteMessage(tokenId) {
|
|
18
|
+
return `Delete: ${tokenId}`;
|
|
19
|
+
}
|
package/dist/utils.js
CHANGED
|
@@ -26,6 +26,7 @@ exports.getTorusKeys = getTorusKeys;
|
|
|
26
26
|
exports.decryptKeys = decryptKeys;
|
|
27
27
|
exports.getSatsConnectAddress = getSatsConnectAddress;
|
|
28
28
|
exports.signPSBT = signPSBT;
|
|
29
|
+
exports.parseBigIntValue = parseBigIntValue;
|
|
29
30
|
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
30
31
|
const metadata_json_1 = __importDefault(require("./curated/metadata.json"));
|
|
31
32
|
const darkfarms_metadata_json_1 = __importDefault(require("./curated/darkfarms-metadata.json"));
|
|
@@ -596,6 +597,39 @@ function generateTemplate(record) {
|
|
|
596
597
|
nameAndImage.description = nameAndImage.description + viewOnEmblemFinanceLink;
|
|
597
598
|
return nameAndImage;
|
|
598
599
|
},
|
|
600
|
+
fillCreateVaultTemplate: (args, _this) => {
|
|
601
|
+
const template = _this.generateCreateTemplate(_this);
|
|
602
|
+
if (args.fromAddress) {
|
|
603
|
+
template.fromAddress = args.fromAddress;
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
throw new Error("fromAddress is required to create vault");
|
|
607
|
+
}
|
|
608
|
+
if (args.toAddress) {
|
|
609
|
+
template.toAddress = args.toAddress;
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
throw new Error("toAddress is required to create vault");
|
|
613
|
+
}
|
|
614
|
+
if (args.chainId) {
|
|
615
|
+
const chainIdAsString = String(args.chainId);
|
|
616
|
+
template.targetContract = {
|
|
617
|
+
name: template.targetContract.name,
|
|
618
|
+
[chainIdAsString]: template.targetContract[chainIdAsString]
|
|
619
|
+
};
|
|
620
|
+
template.chainId = args.chainId;
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
throw new Error("chainId is required to create vault");
|
|
624
|
+
}
|
|
625
|
+
if (args.targetAsset) {
|
|
626
|
+
Object.assign(template.targetAsset, args.targetAsset);
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
template.targetAsset = undefined;
|
|
630
|
+
}
|
|
631
|
+
return template;
|
|
632
|
+
},
|
|
599
633
|
generateCreateTemplate: (_this) => {
|
|
600
634
|
let template = {
|
|
601
635
|
fromAddress: { type: "user-provided" },
|
|
@@ -952,3 +986,9 @@ function signPSBT(psbtBase64_1, paymentAddress_1, indexes_1) {
|
|
|
952
986
|
});
|
|
953
987
|
});
|
|
954
988
|
}
|
|
989
|
+
function parseBigIntValue(value) {
|
|
990
|
+
if (typeof value === 'object' && value !== null && 'hex' in value) {
|
|
991
|
+
return BigInt(value.hex);
|
|
992
|
+
}
|
|
993
|
+
return BigInt(String(value));
|
|
994
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isV2Vault = isV2Vault;
|
|
4
|
+
exports.requiresOnChainUnvault = requiresOnChainUnvault;
|
|
5
|
+
exports.getClaimIdentifier = getClaimIdentifier;
|
|
6
|
+
exports.getHandlerContractAddress = getHandlerContractAddress;
|
|
7
|
+
exports.getUnvaultingContractAddress = getUnvaultingContractAddress;
|
|
8
|
+
exports.getChainConfig = getChainConfig;
|
|
9
|
+
exports.isEvmChain = isEvmChain;
|
|
10
|
+
const constants_1 = require("./constants");
|
|
11
|
+
function isV2Vault(metadata) {
|
|
12
|
+
var _a;
|
|
13
|
+
return Boolean((_a = metadata.targetContract) === null || _a === void 0 ? void 0 : _a.name);
|
|
14
|
+
}
|
|
15
|
+
function requiresOnChainUnvault(metadata) {
|
|
16
|
+
return metadata.status === 'unclaimed' && !metadata.sealed && Boolean(metadata.live);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get the claim identifier for signing claim messages.
|
|
20
|
+
* This MUST match VaultActions.vue's getSerialNumber() logic:
|
|
21
|
+
* - ERC1155: use targetContract.serialNumber
|
|
22
|
+
* - ERC721a: use tokenId
|
|
23
|
+
* - Legacy: use tokenId
|
|
24
|
+
*/
|
|
25
|
+
function getClaimIdentifier(metadata) {
|
|
26
|
+
const { targetContract, ownershipInfo, tokenId } = metadata;
|
|
27
|
+
// If no targetContract, fallback to tokenId
|
|
28
|
+
if (!targetContract) {
|
|
29
|
+
return tokenId || '';
|
|
30
|
+
}
|
|
31
|
+
// ERC1155: use serialNumber
|
|
32
|
+
if (targetContract.collectionType === 'ERC1155' ||
|
|
33
|
+
(ownershipInfo === null || ownershipInfo === void 0 ? void 0 : ownershipInfo.category) === 'erc1155') {
|
|
34
|
+
return targetContract.serialNumber || tokenId || '';
|
|
35
|
+
}
|
|
36
|
+
// ERC721a: use tokenId (NOT serialNumber!)
|
|
37
|
+
if (targetContract.collectionType === 'ERC721a' ||
|
|
38
|
+
(ownershipInfo === null || ownershipInfo === void 0 ? void 0 : ownershipInfo.category) === 'erc721a') {
|
|
39
|
+
return tokenId || '';
|
|
40
|
+
}
|
|
41
|
+
// Default: use targetContract.tokenId or tokenId
|
|
42
|
+
return targetContract.tokenId || tokenId || '';
|
|
43
|
+
}
|
|
44
|
+
function getHandlerContractAddress(chainId) {
|
|
45
|
+
const config = getChainConfig(chainId);
|
|
46
|
+
if (!config.handlerContract) {
|
|
47
|
+
throw new Error(`No handler contract configured for chain ${chainId}`);
|
|
48
|
+
}
|
|
49
|
+
return config.handlerContract;
|
|
50
|
+
}
|
|
51
|
+
function getUnvaultingContractAddress(chainId) {
|
|
52
|
+
const config = getChainConfig(chainId);
|
|
53
|
+
if (!config.unvaultingContract) {
|
|
54
|
+
throw new Error(`No unvaulting contract configured for chain ${chainId}`);
|
|
55
|
+
}
|
|
56
|
+
return config.unvaultingContract;
|
|
57
|
+
}
|
|
58
|
+
function getChainConfig(chainId) {
|
|
59
|
+
const config = constants_1.SUPPORTED_CHAINS[chainId];
|
|
60
|
+
if (!config) {
|
|
61
|
+
const supportedList = Object.entries(constants_1.SUPPORTED_CHAINS)
|
|
62
|
+
.map(([id, cfg]) => `${cfg.name} (${id})`)
|
|
63
|
+
.join(', ');
|
|
64
|
+
throw new Error(`Unsupported chain: ${chainId}. Supported chains: ${supportedList}`);
|
|
65
|
+
}
|
|
66
|
+
return config;
|
|
67
|
+
}
|
|
68
|
+
function isEvmChain(chainId) {
|
|
69
|
+
const config = constants_1.SUPPORTED_CHAINS[chainId];
|
|
70
|
+
return (config === null || config === void 0 ? void 0 : config.type) === 'evm';
|
|
71
|
+
}
|