emblem-vault-sdk 2.11.0 → 2.12.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/abi/abi.json +79 -3
- package/dist/evm-operations.js +96 -7
- package/dist/index.js +106 -13
- package/package.json +2 -2
- package/src/abi/abi.json +79 -3
- package/src/evm-operations.ts +120 -10
- package/src/index.ts +116 -18
- package/types/evm-operations.d.ts +3 -0
- package/types/index.d.ts +7 -0
package/dist/abi/abi.json
CHANGED
|
@@ -78,18 +78,18 @@
|
|
|
78
78
|
"inputs": [
|
|
79
79
|
{
|
|
80
80
|
"internalType": "address",
|
|
81
|
-
"name": "
|
|
81
|
+
"name": "",
|
|
82
82
|
"type": "address"
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"internalType": "uint256",
|
|
86
|
-
"name": "
|
|
86
|
+
"name": "",
|
|
87
87
|
"type": "uint256"
|
|
88
88
|
}
|
|
89
89
|
],
|
|
90
90
|
"name": "claim",
|
|
91
91
|
"outputs": [],
|
|
92
|
-
"stateMutability": "
|
|
92
|
+
"stateMutability": "pure",
|
|
93
93
|
"type": "function"
|
|
94
94
|
},
|
|
95
95
|
{
|
|
@@ -144,6 +144,82 @@
|
|
|
144
144
|
"outputs": [],
|
|
145
145
|
"stateMutability": "payable",
|
|
146
146
|
"type": "function"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"inputs": [
|
|
150
|
+
{
|
|
151
|
+
"internalType": "address",
|
|
152
|
+
"name": "_nftAddress",
|
|
153
|
+
"type": "address"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"internalType": "uint256",
|
|
157
|
+
"name": "tokenId",
|
|
158
|
+
"type": "uint256"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"internalType": "address",
|
|
162
|
+
"name": "_payment",
|
|
163
|
+
"type": "address"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"internalType": "uint256",
|
|
167
|
+
"name": "_price",
|
|
168
|
+
"type": "uint256"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"internalType": "uint256",
|
|
172
|
+
"name": "_nonce",
|
|
173
|
+
"type": "uint256"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"internalType": "bytes",
|
|
177
|
+
"name": "_signature",
|
|
178
|
+
"type": "bytes"
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
"name": "claimWithSignedPrice",
|
|
182
|
+
"outputs": [],
|
|
183
|
+
"stateMutability": "payable",
|
|
184
|
+
"type": "function"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"inputs": [
|
|
188
|
+
{
|
|
189
|
+
"internalType": "address[]",
|
|
190
|
+
"name": "nftAddresses",
|
|
191
|
+
"type": "address[]"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"internalType": "uint256[]",
|
|
195
|
+
"name": "tokenIds",
|
|
196
|
+
"type": "uint256[]"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"internalType": "address",
|
|
200
|
+
"name": "_payment",
|
|
201
|
+
"type": "address"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"internalType": "uint256",
|
|
205
|
+
"name": "_price",
|
|
206
|
+
"type": "uint256"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"internalType": "uint256",
|
|
210
|
+
"name": "_nonce",
|
|
211
|
+
"type": "uint256"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"internalType": "bytes",
|
|
215
|
+
"name": "_signature",
|
|
216
|
+
"type": "bytes"
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
"name": "batchClaimWithSignedPrice",
|
|
220
|
+
"outputs": [],
|
|
221
|
+
"stateMutability": "payable",
|
|
222
|
+
"type": "function"
|
|
147
223
|
}
|
|
148
224
|
],
|
|
149
225
|
"legacy": [
|
package/dist/evm-operations.js
CHANGED
|
@@ -45,6 +45,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
45
45
|
exports.performMintEvm = performMintEvm;
|
|
46
46
|
exports.performClaimEvm = performClaimEvm;
|
|
47
47
|
exports.deleteVaultEvm = deleteVaultEvm;
|
|
48
|
+
exports.performBatchClaimEvm = performBatchClaimEvm;
|
|
48
49
|
const constants_1 = require("./constants");
|
|
49
50
|
const signing_messages_1 = require("./signing-messages");
|
|
50
51
|
const vault_utils_1 = require("./vault-utils");
|
|
@@ -97,7 +98,7 @@ function performClaimEvm(ctx, client, tokenId, chainId, metadata, claimIdentifie
|
|
|
97
98
|
const targetContractAddress = ((_b = metadata.targetContract) === null || _b === void 0 ? void 0 : _b[chainId]) || metadata.collectionAddress;
|
|
98
99
|
if (targetContractAddress) {
|
|
99
100
|
callback === null || callback === void 0 ? void 0 : callback('Performing on-chain claim...');
|
|
100
|
-
yield performLegacyClaim(wallet, targetContractAddress, claimIdentifier, chainId, callback);
|
|
101
|
+
yield performLegacyClaim(ctx, wallet, targetContractAddress, claimIdentifier, chainId, callback);
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
}
|
|
@@ -211,29 +212,117 @@ function performOnChainUnvault(ctx, wallet, tokenId, claimIdentifier, nftAddress
|
|
|
211
212
|
* Perform legacy claim by calling the handler contract's claim function
|
|
212
213
|
* This is for non-V2 vaults that don't use signed price unvaulting
|
|
213
214
|
*/
|
|
214
|
-
function performLegacyClaim(wallet, targetContractAddress, tokenId, chainId, callback) {
|
|
215
|
+
function performLegacyClaim(ctx, wallet, targetContractAddress, tokenId, chainId, callback) {
|
|
215
216
|
return __awaiter(this, void 0, void 0, function* () {
|
|
216
217
|
const { ethers } = yield Promise.resolve().then(() => __importStar(require('ethers')));
|
|
217
|
-
//
|
|
218
|
+
// The handler's free claim(address,uint256) was retired; claiming requires a
|
|
219
|
+
// witness-signed price via claimWithSignedPrice. Sign "Claim: <tokenId>", get
|
|
220
|
+
// the server-signed price for this asset (supply tier), then call the contract
|
|
221
|
+
// with the server-derived on-chain tokenId + payment.
|
|
222
|
+
callback === null || callback === void 0 ? void 0 : callback('Signing claim authorization...');
|
|
223
|
+
const claimSig = yield wallet.signMessage(`Claim: ${tokenId}`);
|
|
224
|
+
callback === null || callback === void 0 ? void 0 : callback('Requesting claim price...');
|
|
225
|
+
const remote = yield requestRemoteClaimSignature(ctx, tokenId, claimSig, chainId);
|
|
218
226
|
const HANDLER_CLAIM_ABI = [
|
|
219
|
-
'function
|
|
227
|
+
'function claimWithSignedPrice(address _nftAddress, uint256 tokenId, address _payment, uint256 _price, uint256 _nonce, bytes _signature) external payable'
|
|
220
228
|
];
|
|
221
229
|
const handlerAddress = (0, vault_utils_1.getHandlerContractAddress)(chainId);
|
|
222
230
|
const iface = new ethers.utils.Interface(HANDLER_CLAIM_ABI);
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
231
|
+
const price = ethers.BigNumber.from(remote._price);
|
|
232
|
+
const isEth = remote._payment === '0x0000000000000000000000000000000000000000';
|
|
233
|
+
const data = iface.encodeFunctionData('claimWithSignedPrice', [
|
|
234
|
+
remote._nftAddress,
|
|
235
|
+
ethers.BigNumber.from(remote._tokenId),
|
|
236
|
+
remote._payment,
|
|
237
|
+
price,
|
|
238
|
+
ethers.BigNumber.from(remote._nonce),
|
|
239
|
+
remote._signature,
|
|
226
240
|
]);
|
|
227
241
|
callback === null || callback === void 0 ? void 0 : callback('Submitting claim transaction...');
|
|
228
242
|
const tx = yield wallet.sendTransaction({
|
|
229
243
|
to: handlerAddress,
|
|
230
244
|
data,
|
|
245
|
+
value: isEth ? price : ethers.constants.Zero,
|
|
231
246
|
});
|
|
232
247
|
callback === null || callback === void 0 ? void 0 : callback('Waiting for claim confirmation...', { txHash: tx.hash });
|
|
233
248
|
yield tx.wait();
|
|
234
249
|
callback === null || callback === void 0 ? void 0 : callback('On-chain claim complete!');
|
|
235
250
|
});
|
|
236
251
|
}
|
|
252
|
+
// Witness signature + supply-tier price for a legacy (non-diamond) claim.
|
|
253
|
+
function requestRemoteClaimSignature(ctx, tokenId, signature, chainId) {
|
|
254
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
255
|
+
const response = yield fetch(`${ctx.baseUrl}/claim-curated`, {
|
|
256
|
+
method: 'POST',
|
|
257
|
+
headers: { 'Content-Type': 'application/json' },
|
|
258
|
+
body: JSON.stringify({ tokenId, signature, chainId: chainId.toString() }),
|
|
259
|
+
});
|
|
260
|
+
const remote = yield response.json();
|
|
261
|
+
if (!(remote === null || remote === void 0 ? void 0 : remote.success)) {
|
|
262
|
+
throw new Error((remote === null || remote === void 0 ? void 0 : remote.msg) || (remote === null || remote === void 0 ? void 0 : remote.error) || 'Failed to get claim signature');
|
|
263
|
+
}
|
|
264
|
+
return remote;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
// Batch witness signature + summed supply-tier price for several vaults.
|
|
268
|
+
function requestRemoteBatchClaimSignature(ctx, tokenIds, signature, chainId) {
|
|
269
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
270
|
+
const response = yield fetch(`${ctx.baseUrl}/claim-curated-bulk`, {
|
|
271
|
+
method: 'POST',
|
|
272
|
+
headers: { 'Content-Type': 'application/json' },
|
|
273
|
+
body: JSON.stringify({ tokenIds, signature, chainId: chainId.toString() }),
|
|
274
|
+
});
|
|
275
|
+
const remote = yield response.json();
|
|
276
|
+
if (!(remote === null || remote === void 0 ? void 0 : remote.success)) {
|
|
277
|
+
throw new Error((remote === null || remote === void 0 ? void 0 : remote.msg) || (remote === null || remote === void 0 ? void 0 : remote.error) || 'Failed to get batch claim signature');
|
|
278
|
+
}
|
|
279
|
+
return remote;
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
// Client path: burn several vaults in one tx via batchClaimWithSignedPrice. Only
|
|
283
|
+
// performs the on-chain claim (Step 1) for the batch; reveal each vault's keys
|
|
284
|
+
// with performClaimChainWithClient afterward (which will skip Step 1 as claimed).
|
|
285
|
+
function performBatchClaimEvm(ctx, client, tokenIds, chainId, callback) {
|
|
286
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
287
|
+
var _a;
|
|
288
|
+
callback === null || callback === void 0 ? void 0 : callback('Initializing EVM signer...');
|
|
289
|
+
const { ethers } = yield Promise.resolve().then(() => __importStar(require('ethers')));
|
|
290
|
+
const provider = new ethers.providers.JsonRpcProvider(getEvmRpcUrl(chainId));
|
|
291
|
+
const wallet = yield client.toEthersWallet(provider);
|
|
292
|
+
(_a = wallet.setChainId) === null || _a === void 0 ? void 0 : _a.call(wallet, chainId);
|
|
293
|
+
// One wallet signature over the sorted, comma-joined ids (order-independent).
|
|
294
|
+
const sorted = [...tokenIds.map(String)].sort().join(',');
|
|
295
|
+
callback === null || callback === void 0 ? void 0 : callback('Signing batch claim authorization...');
|
|
296
|
+
const signature = yield wallet.signMessage(`Claim: ${sorted}`);
|
|
297
|
+
callback === null || callback === void 0 ? void 0 : callback('Requesting batch claim price...');
|
|
298
|
+
const remote = yield requestRemoteBatchClaimSignature(ctx, tokenIds, signature, chainId);
|
|
299
|
+
const HANDLER_BATCH_ABI = [
|
|
300
|
+
'function batchClaimWithSignedPrice(address[] nftAddresses, uint256[] tokenIds, address _payment, uint256 _price, uint256 _nonce, bytes _signature) external payable'
|
|
301
|
+
];
|
|
302
|
+
const handlerAddress = (0, vault_utils_1.getHandlerContractAddress)(chainId);
|
|
303
|
+
const iface = new ethers.utils.Interface(HANDLER_BATCH_ABI);
|
|
304
|
+
const price = ethers.BigNumber.from(remote._price);
|
|
305
|
+
const isEth = remote._payment === constants_1.ZERO_ADDRESS;
|
|
306
|
+
const data = iface.encodeFunctionData('batchClaimWithSignedPrice', [
|
|
307
|
+
remote._nftAddresses,
|
|
308
|
+
remote._tokenIds.map((t) => ethers.BigNumber.from(t)),
|
|
309
|
+
remote._payment,
|
|
310
|
+
price,
|
|
311
|
+
ethers.BigNumber.from(remote._nonce),
|
|
312
|
+
remote._signature,
|
|
313
|
+
]);
|
|
314
|
+
callback === null || callback === void 0 ? void 0 : callback('Submitting batch claim transaction...');
|
|
315
|
+
const tx = yield wallet.sendTransaction({
|
|
316
|
+
to: handlerAddress,
|
|
317
|
+
data,
|
|
318
|
+
value: isEth ? price : ethers.constants.Zero,
|
|
319
|
+
});
|
|
320
|
+
callback === null || callback === void 0 ? void 0 : callback('Waiting for batch claim confirmation...', { txHash: tx.hash });
|
|
321
|
+
yield tx.wait();
|
|
322
|
+
callback === null || callback === void 0 ? void 0 : callback('On-chain batch claim complete!');
|
|
323
|
+
return { txHash: tx.hash };
|
|
324
|
+
});
|
|
325
|
+
}
|
|
237
326
|
function requestRemoteUnvaultSignature(ctx, tokenId, signature, chainId) {
|
|
238
327
|
return __awaiter(this, void 0, void 0, function* () {
|
|
239
328
|
const response = yield fetch(`${ctx.baseUrl}/unvault-curated`, {
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ const derive_1 = require("./derive");
|
|
|
48
48
|
const constants_1 = require("./constants");
|
|
49
49
|
const vault_utils_1 = require("./vault-utils");
|
|
50
50
|
const evm_operations_1 = require("./evm-operations");
|
|
51
|
-
const SDK_VERSION = '2.
|
|
51
|
+
const SDK_VERSION = '2.12.0';
|
|
52
52
|
class EmblemVaultSDK {
|
|
53
53
|
constructor(apiKey, baseUrl, v3Url, sigUrl) {
|
|
54
54
|
this.apiKey = apiKey;
|
|
@@ -455,6 +455,25 @@ class EmblemVaultSDK {
|
|
|
455
455
|
return remoteMintResponse;
|
|
456
456
|
});
|
|
457
457
|
}
|
|
458
|
+
// Witness signature + supply-tier price for a claim (the on-chain burn before
|
|
459
|
+
// key reveal). `signature` is the user's "Claim: <tokenId>" wallet signature.
|
|
460
|
+
requestRemoteClaimSignature(web3_1, tokenId_1, signature_1) {
|
|
461
|
+
return __awaiter(this, arguments, void 0, function* (web3, tokenId, signature, callback = null) {
|
|
462
|
+
if (callback) {
|
|
463
|
+
callback('requesting Remote Claim signature');
|
|
464
|
+
}
|
|
465
|
+
const chainId = yield web3.eth.getChainId();
|
|
466
|
+
let url = `${this.baseUrl}/claim-curated`;
|
|
467
|
+
let remoteClaimResponse = yield (0, utils_1.fetchData)(url, this.apiKey, 'POST', { tokenId: tokenId, signature: signature, chainId: chainId.toString() });
|
|
468
|
+
if (remoteClaimResponse.error || remoteClaimResponse.err) {
|
|
469
|
+
throw new Error(remoteClaimResponse.error || remoteClaimResponse.msg || 'Failed to get claim signature');
|
|
470
|
+
}
|
|
471
|
+
if (callback) {
|
|
472
|
+
callback(`remote Claim signature`, remoteClaimResponse);
|
|
473
|
+
}
|
|
474
|
+
return remoteClaimResponse;
|
|
475
|
+
});
|
|
476
|
+
}
|
|
458
477
|
// ** Bulk Mint **
|
|
459
478
|
//
|
|
460
479
|
// Builds the deterministic message a user signs to authorize a bulk curated
|
|
@@ -639,24 +658,25 @@ class EmblemVaultSDK {
|
|
|
639
658
|
}
|
|
640
659
|
performBurn(web3_1, tokenId_1) {
|
|
641
660
|
return __awaiter(this, arguments, void 0, function* (web3, tokenId, callback = null) {
|
|
642
|
-
let metadata = yield this.fetchMetadata(tokenId);
|
|
643
|
-
let targetContract = yield this.fetchCuratedContractByName(metadata.targetContract.name);
|
|
644
661
|
if (callback) {
|
|
645
662
|
callback('performing Burn');
|
|
646
663
|
}
|
|
647
664
|
const accounts = yield web3.eth.getAccounts();
|
|
648
|
-
const chainId = yield web3.eth.getChainId();
|
|
649
665
|
let handlerContract = yield (0, utils_1.getHandlerContract)(web3);
|
|
650
|
-
//
|
|
666
|
+
// The handler no longer has a free claim(address,uint256); claiming requires
|
|
667
|
+
// a witness-signed price via claimWithSignedPrice. Get the user's "Claim:"
|
|
668
|
+
// signature, then the server-signed price for this asset (supply tier), then
|
|
669
|
+
// call claimWithSignedPrice with the server-derived on-chain tokenId + payment.
|
|
670
|
+
const claimSig = yield this.requestLocalClaimSignature(web3, tokenId, null, callback);
|
|
671
|
+
const remote = yield this.requestRemoteClaimSignature(web3, tokenId, claimSig, callback);
|
|
672
|
+
const price = remote._price;
|
|
673
|
+
const isEth = remote._payment === '0x0000000000000000000000000000000000000000';
|
|
651
674
|
const gasPrice = yield web3.eth.getGasPrice();
|
|
652
|
-
let createdTxObject = handlerContract.methods.
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
let burnResponse = yield createdTxObject.send(
|
|
656
|
-
|
|
657
|
-
gasPrice: gasPrice,
|
|
658
|
-
gas: estimatedGas
|
|
659
|
-
}).on('transactionHash', (hash) => {
|
|
675
|
+
let createdTxObject = handlerContract.methods.claimWithSignedPrice(remote._nftAddress, remote._tokenId, remote._payment, price, remote._nonce, remote._signature);
|
|
676
|
+
const sendOpts = { from: accounts[0], gasPrice, value: isEth ? price : '0' };
|
|
677
|
+
sendOpts.gas = yield createdTxObject.estimateGas(sendOpts);
|
|
678
|
+
let burnResponse = yield createdTxObject.send(sendOpts)
|
|
679
|
+
.on('transactionHash', (hash) => {
|
|
660
680
|
if (callback)
|
|
661
681
|
callback(`Transaction submitted. Hash`, hash);
|
|
662
682
|
})
|
|
@@ -674,6 +694,71 @@ class EmblemVaultSDK {
|
|
|
674
694
|
return burnResponse;
|
|
675
695
|
});
|
|
676
696
|
}
|
|
697
|
+
// Wallet signature authorizing a batch claim. Must match the server's expected
|
|
698
|
+
// message: "Claim: <sorted tokenIds joined by ','>" (order-independent).
|
|
699
|
+
requestLocalBatchClaimSignature(web3_1, tokenIds_1) {
|
|
700
|
+
return __awaiter(this, arguments, void 0, function* (web3, tokenIds, callback = null) {
|
|
701
|
+
if (callback) {
|
|
702
|
+
callback('requesting User Batch Claim Signature');
|
|
703
|
+
}
|
|
704
|
+
const sorted = [...tokenIds.map(String)].sort().join(',');
|
|
705
|
+
const message = `Claim: ${sorted}`;
|
|
706
|
+
const accounts = yield web3.eth.getAccounts();
|
|
707
|
+
const signature = yield web3.eth.personal.sign(message, accounts[0], '');
|
|
708
|
+
return signature;
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
// Fetch the batch witness signature + summed supply-tier price for several vaults.
|
|
712
|
+
requestRemoteBatchClaimSignature(web3_1, tokenIds_1, signature_1) {
|
|
713
|
+
return __awaiter(this, arguments, void 0, function* (web3, tokenIds, signature, callback = null) {
|
|
714
|
+
if (callback) {
|
|
715
|
+
callback('requesting Remote Batch Claim signature');
|
|
716
|
+
}
|
|
717
|
+
const chainId = yield web3.eth.getChainId();
|
|
718
|
+
let url = `${this.baseUrl}/claim-curated-bulk`;
|
|
719
|
+
let remote = yield (0, utils_1.fetchData)(url, this.apiKey, 'POST', { tokenIds, signature, chainId: chainId.toString() });
|
|
720
|
+
if (remote.error || remote.err || remote.success === false) {
|
|
721
|
+
throw new Error(remote.error || remote.msg || 'Failed to get batch claim signature');
|
|
722
|
+
}
|
|
723
|
+
return remote;
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
// Burn several vaults in one tx via batchClaimWithSignedPrice. One wallet
|
|
727
|
+
// signature + one witness signature + summed supply-tier price for the batch.
|
|
728
|
+
performBatchBurn(web3_1, tokenIds_1) {
|
|
729
|
+
return __awaiter(this, arguments, void 0, function* (web3, tokenIds, callback = null) {
|
|
730
|
+
if (callback) {
|
|
731
|
+
callback('performing Batch Burn');
|
|
732
|
+
}
|
|
733
|
+
const accounts = yield web3.eth.getAccounts();
|
|
734
|
+
let handlerContract = yield (0, utils_1.getHandlerContract)(web3);
|
|
735
|
+
const claimSig = yield this.requestLocalBatchClaimSignature(web3, tokenIds, callback);
|
|
736
|
+
const remote = yield this.requestRemoteBatchClaimSignature(web3, tokenIds, claimSig, callback);
|
|
737
|
+
const price = remote._price;
|
|
738
|
+
const isEth = remote._payment === '0x0000000000000000000000000000000000000000';
|
|
739
|
+
const value = isEth ? price : '0';
|
|
740
|
+
const gasPrice = yield web3.eth.getGasPrice();
|
|
741
|
+
let createdTxObject = handlerContract.methods.batchClaimWithSignedPrice(remote._nftAddresses, remote._tokenIds, remote._payment, price, remote._nonce, remote._signature);
|
|
742
|
+
const gas = yield createdTxObject.estimateGas({ from: accounts[0], value });
|
|
743
|
+
let burnResponse = yield createdTxObject.send({ from: accounts[0], value, gasPrice, gas })
|
|
744
|
+
.on('transactionHash', (hash) => {
|
|
745
|
+
if (callback)
|
|
746
|
+
callback(`Transaction submitted. Hash`, hash);
|
|
747
|
+
})
|
|
748
|
+
.on('confirmation', (confirmationNumber, receipt) => {
|
|
749
|
+
if (callback)
|
|
750
|
+
callback(`Batch Burn Complete. Confirmation Number`, confirmationNumber);
|
|
751
|
+
})
|
|
752
|
+
.on('error', (error) => {
|
|
753
|
+
if (callback)
|
|
754
|
+
callback(`Transaction Error`, error.message);
|
|
755
|
+
});
|
|
756
|
+
if (callback) {
|
|
757
|
+
callback('Batch Burn Complete');
|
|
758
|
+
}
|
|
759
|
+
return burnResponse;
|
|
760
|
+
});
|
|
761
|
+
}
|
|
677
762
|
contentTypeReport(url) {
|
|
678
763
|
return __awaiter(this, void 0, void 0, function* () {
|
|
679
764
|
return yield (0, utils_1.checkContentType)(url);
|
|
@@ -768,6 +853,14 @@ class EmblemVaultSDK {
|
|
|
768
853
|
return (0, evm_operations_1.performClaimEvm)(this.getSdkContext(), client, tokenId, chainId, metadata, claimIdentifier, vaultIsV2, needsOnChainUnvault, callback);
|
|
769
854
|
});
|
|
770
855
|
}
|
|
856
|
+
// Client-path batch claim: burn several vaults in one tx (Step 1 only). Reveal
|
|
857
|
+
// each vault's keys afterward with performClaimChainWithClient (skips Step 1).
|
|
858
|
+
performBatchBurnWithClient(client_1, tokenIds_1) {
|
|
859
|
+
return __awaiter(this, arguments, void 0, function* (client, tokenIds, chainId = constants_1.ETHEREUM_MAINNET_CHAIN_ID, callback) {
|
|
860
|
+
(0, vault_utils_1.getChainConfig)(chainId);
|
|
861
|
+
return (0, evm_operations_1.performBatchClaimEvm)(this.getSdkContext(), client, tokenIds, chainId, callback);
|
|
862
|
+
});
|
|
863
|
+
}
|
|
771
864
|
deleteVaultWithClient(client_1, tokenId_1) {
|
|
772
865
|
return __awaiter(this, arguments, void 0, function* (client, tokenId, chainId = constants_1.ETHEREUM_MAINNET_CHAIN_ID, callback) {
|
|
773
866
|
(0, utils_1.genericGuard)(tokenId, "string", "tokenId");
|
package/package.json
CHANGED
package/src/abi/abi.json
CHANGED
|
@@ -78,18 +78,18 @@
|
|
|
78
78
|
"inputs": [
|
|
79
79
|
{
|
|
80
80
|
"internalType": "address",
|
|
81
|
-
"name": "
|
|
81
|
+
"name": "",
|
|
82
82
|
"type": "address"
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"internalType": "uint256",
|
|
86
|
-
"name": "
|
|
86
|
+
"name": "",
|
|
87
87
|
"type": "uint256"
|
|
88
88
|
}
|
|
89
89
|
],
|
|
90
90
|
"name": "claim",
|
|
91
91
|
"outputs": [],
|
|
92
|
-
"stateMutability": "
|
|
92
|
+
"stateMutability": "pure",
|
|
93
93
|
"type": "function"
|
|
94
94
|
},
|
|
95
95
|
{
|
|
@@ -144,6 +144,82 @@
|
|
|
144
144
|
"outputs": [],
|
|
145
145
|
"stateMutability": "payable",
|
|
146
146
|
"type": "function"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"inputs": [
|
|
150
|
+
{
|
|
151
|
+
"internalType": "address",
|
|
152
|
+
"name": "_nftAddress",
|
|
153
|
+
"type": "address"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"internalType": "uint256",
|
|
157
|
+
"name": "tokenId",
|
|
158
|
+
"type": "uint256"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"internalType": "address",
|
|
162
|
+
"name": "_payment",
|
|
163
|
+
"type": "address"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"internalType": "uint256",
|
|
167
|
+
"name": "_price",
|
|
168
|
+
"type": "uint256"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"internalType": "uint256",
|
|
172
|
+
"name": "_nonce",
|
|
173
|
+
"type": "uint256"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"internalType": "bytes",
|
|
177
|
+
"name": "_signature",
|
|
178
|
+
"type": "bytes"
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
"name": "claimWithSignedPrice",
|
|
182
|
+
"outputs": [],
|
|
183
|
+
"stateMutability": "payable",
|
|
184
|
+
"type": "function"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"inputs": [
|
|
188
|
+
{
|
|
189
|
+
"internalType": "address[]",
|
|
190
|
+
"name": "nftAddresses",
|
|
191
|
+
"type": "address[]"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"internalType": "uint256[]",
|
|
195
|
+
"name": "tokenIds",
|
|
196
|
+
"type": "uint256[]"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"internalType": "address",
|
|
200
|
+
"name": "_payment",
|
|
201
|
+
"type": "address"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"internalType": "uint256",
|
|
205
|
+
"name": "_price",
|
|
206
|
+
"type": "uint256"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"internalType": "uint256",
|
|
210
|
+
"name": "_nonce",
|
|
211
|
+
"type": "uint256"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"internalType": "bytes",
|
|
215
|
+
"name": "_signature",
|
|
216
|
+
"type": "bytes"
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
"name": "batchClaimWithSignedPrice",
|
|
220
|
+
"outputs": [],
|
|
221
|
+
"stateMutability": "payable",
|
|
222
|
+
"type": "function"
|
|
147
223
|
}
|
|
148
224
|
],
|
|
149
225
|
"legacy": [
|
package/src/evm-operations.ts
CHANGED
|
@@ -105,7 +105,7 @@ export async function performClaimEvm(
|
|
|
105
105
|
const targetContractAddress = metadata.targetContract?.[chainId] || metadata.collectionAddress;
|
|
106
106
|
if (targetContractAddress) {
|
|
107
107
|
callback?.('Performing on-chain claim...');
|
|
108
|
-
await performLegacyClaim(wallet, targetContractAddress, claimIdentifier, chainId, callback);
|
|
108
|
+
await performLegacyClaim(ctx, wallet, targetContractAddress, claimIdentifier, chainId, callback);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -262,6 +262,7 @@ async function performOnChainUnvault(
|
|
|
262
262
|
* This is for non-V2 vaults that don't use signed price unvaulting
|
|
263
263
|
*/
|
|
264
264
|
async function performLegacyClaim(
|
|
265
|
+
ctx: SdkContext,
|
|
265
266
|
wallet: EvmSigner,
|
|
266
267
|
targetContractAddress: string,
|
|
267
268
|
tokenId: string,
|
|
@@ -269,32 +270,141 @@ async function performLegacyClaim(
|
|
|
269
270
|
callback?: ProgressCallback
|
|
270
271
|
): Promise<void> {
|
|
271
272
|
const { ethers } = await import('ethers');
|
|
272
|
-
|
|
273
|
-
//
|
|
273
|
+
|
|
274
|
+
// The handler's free claim(address,uint256) was retired; claiming requires a
|
|
275
|
+
// witness-signed price via claimWithSignedPrice. Sign "Claim: <tokenId>", get
|
|
276
|
+
// the server-signed price for this asset (supply tier), then call the contract
|
|
277
|
+
// with the server-derived on-chain tokenId + payment.
|
|
278
|
+
callback?.('Signing claim authorization...');
|
|
279
|
+
const claimSig = await wallet.signMessage(`Claim: ${tokenId}`);
|
|
280
|
+
|
|
281
|
+
callback?.('Requesting claim price...');
|
|
282
|
+
const remote = await requestRemoteClaimSignature(ctx, tokenId, claimSig, chainId);
|
|
283
|
+
|
|
274
284
|
const HANDLER_CLAIM_ABI = [
|
|
275
|
-
'function
|
|
285
|
+
'function claimWithSignedPrice(address _nftAddress, uint256 tokenId, address _payment, uint256 _price, uint256 _nonce, bytes _signature) external payable'
|
|
276
286
|
];
|
|
277
|
-
|
|
278
287
|
const handlerAddress = getHandlerContractAddress(chainId);
|
|
279
288
|
const iface = new ethers.utils.Interface(HANDLER_CLAIM_ABI);
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
289
|
+
|
|
290
|
+
const price = ethers.BigNumber.from(remote._price);
|
|
291
|
+
const isEth = remote._payment === '0x0000000000000000000000000000000000000000';
|
|
292
|
+
|
|
293
|
+
const data = iface.encodeFunctionData('claimWithSignedPrice', [
|
|
294
|
+
remote._nftAddress,
|
|
295
|
+
ethers.BigNumber.from(remote._tokenId),
|
|
296
|
+
remote._payment,
|
|
297
|
+
price,
|
|
298
|
+
ethers.BigNumber.from(remote._nonce),
|
|
299
|
+
remote._signature,
|
|
284
300
|
]);
|
|
285
301
|
|
|
286
302
|
callback?.('Submitting claim transaction...');
|
|
287
303
|
const tx = await wallet.sendTransaction({
|
|
288
304
|
to: handlerAddress,
|
|
289
305
|
data,
|
|
306
|
+
value: isEth ? price : ethers.constants.Zero,
|
|
290
307
|
});
|
|
291
308
|
|
|
292
309
|
callback?.('Waiting for claim confirmation...', { txHash: tx.hash });
|
|
293
310
|
await tx.wait();
|
|
294
|
-
|
|
311
|
+
|
|
295
312
|
callback?.('On-chain claim complete!');
|
|
296
313
|
}
|
|
297
314
|
|
|
315
|
+
// Witness signature + supply-tier price for a legacy (non-diamond) claim.
|
|
316
|
+
async function requestRemoteClaimSignature(
|
|
317
|
+
ctx: SdkContext,
|
|
318
|
+
tokenId: string,
|
|
319
|
+
signature: string,
|
|
320
|
+
chainId: number
|
|
321
|
+
): Promise<any> {
|
|
322
|
+
const response = await fetch(`${ctx.baseUrl}/claim-curated`, {
|
|
323
|
+
method: 'POST',
|
|
324
|
+
headers: { 'Content-Type': 'application/json' },
|
|
325
|
+
body: JSON.stringify({ tokenId, signature, chainId: chainId.toString() }),
|
|
326
|
+
});
|
|
327
|
+
const remote = await response.json();
|
|
328
|
+
if (!remote?.success) {
|
|
329
|
+
throw new Error(remote?.msg || remote?.error || 'Failed to get claim signature');
|
|
330
|
+
}
|
|
331
|
+
return remote;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Batch witness signature + summed supply-tier price for several vaults.
|
|
335
|
+
async function requestRemoteBatchClaimSignature(
|
|
336
|
+
ctx: SdkContext,
|
|
337
|
+
tokenIds: string[],
|
|
338
|
+
signature: string,
|
|
339
|
+
chainId: number
|
|
340
|
+
): Promise<any> {
|
|
341
|
+
const response = await fetch(`${ctx.baseUrl}/claim-curated-bulk`, {
|
|
342
|
+
method: 'POST',
|
|
343
|
+
headers: { 'Content-Type': 'application/json' },
|
|
344
|
+
body: JSON.stringify({ tokenIds, signature, chainId: chainId.toString() }),
|
|
345
|
+
});
|
|
346
|
+
const remote = await response.json();
|
|
347
|
+
if (!remote?.success) {
|
|
348
|
+
throw new Error(remote?.msg || remote?.error || 'Failed to get batch claim signature');
|
|
349
|
+
}
|
|
350
|
+
return remote;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Client path: burn several vaults in one tx via batchClaimWithSignedPrice. Only
|
|
354
|
+
// performs the on-chain claim (Step 1) for the batch; reveal each vault's keys
|
|
355
|
+
// with performClaimChainWithClient afterward (which will skip Step 1 as claimed).
|
|
356
|
+
export async function performBatchClaimEvm(
|
|
357
|
+
ctx: SdkContext,
|
|
358
|
+
client: EmblemVaultClient,
|
|
359
|
+
tokenIds: string[],
|
|
360
|
+
chainId: number,
|
|
361
|
+
callback?: ProgressCallback
|
|
362
|
+
): Promise<{ txHash: string }> {
|
|
363
|
+
callback?.('Initializing EVM signer...');
|
|
364
|
+
const { ethers } = await import('ethers');
|
|
365
|
+
const provider = new ethers.providers.JsonRpcProvider(getEvmRpcUrl(chainId));
|
|
366
|
+
const wallet = await client.toEthersWallet(provider);
|
|
367
|
+
wallet.setChainId?.(chainId);
|
|
368
|
+
|
|
369
|
+
// One wallet signature over the sorted, comma-joined ids (order-independent).
|
|
370
|
+
const sorted = [...tokenIds.map(String)].sort().join(',');
|
|
371
|
+
callback?.('Signing batch claim authorization...');
|
|
372
|
+
const signature = await wallet.signMessage(`Claim: ${sorted}`);
|
|
373
|
+
|
|
374
|
+
callback?.('Requesting batch claim price...');
|
|
375
|
+
const remote = await requestRemoteBatchClaimSignature(ctx, tokenIds, signature, chainId);
|
|
376
|
+
|
|
377
|
+
const HANDLER_BATCH_ABI = [
|
|
378
|
+
'function batchClaimWithSignedPrice(address[] nftAddresses, uint256[] tokenIds, address _payment, uint256 _price, uint256 _nonce, bytes _signature) external payable'
|
|
379
|
+
];
|
|
380
|
+
const handlerAddress = getHandlerContractAddress(chainId);
|
|
381
|
+
const iface = new ethers.utils.Interface(HANDLER_BATCH_ABI);
|
|
382
|
+
|
|
383
|
+
const price = ethers.BigNumber.from(remote._price);
|
|
384
|
+
const isEth = remote._payment === ZERO_ADDRESS;
|
|
385
|
+
|
|
386
|
+
const data = iface.encodeFunctionData('batchClaimWithSignedPrice', [
|
|
387
|
+
remote._nftAddresses,
|
|
388
|
+
remote._tokenIds.map((t: string) => ethers.BigNumber.from(t)),
|
|
389
|
+
remote._payment,
|
|
390
|
+
price,
|
|
391
|
+
ethers.BigNumber.from(remote._nonce),
|
|
392
|
+
remote._signature,
|
|
393
|
+
]);
|
|
394
|
+
|
|
395
|
+
callback?.('Submitting batch claim transaction...');
|
|
396
|
+
const tx = await wallet.sendTransaction({
|
|
397
|
+
to: handlerAddress,
|
|
398
|
+
data,
|
|
399
|
+
value: isEth ? price : ethers.constants.Zero,
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
callback?.('Waiting for batch claim confirmation...', { txHash: tx.hash });
|
|
403
|
+
await tx.wait();
|
|
404
|
+
callback?.('On-chain batch claim complete!');
|
|
405
|
+
return { txHash: tx.hash };
|
|
406
|
+
}
|
|
407
|
+
|
|
298
408
|
async function requestRemoteUnvaultSignature(
|
|
299
409
|
ctx: SdkContext,
|
|
300
410
|
tokenId: string,
|
package/src/index.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
requiresOnChainUnvault,
|
|
25
25
|
getClaimIdentifier,
|
|
26
26
|
} from './vault-utils';
|
|
27
|
-
import { performMintEvm, performClaimEvm, deleteVaultEvm } from './evm-operations';
|
|
27
|
+
import { performMintEvm, performClaimEvm, performBatchClaimEvm, deleteVaultEvm } from './evm-operations';
|
|
28
28
|
|
|
29
29
|
const SDK_VERSION = '__SDK_VERSION__';
|
|
30
30
|
|
|
@@ -401,6 +401,20 @@ class EmblemVaultSDK {
|
|
|
401
401
|
return remoteMintResponse
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
+
// Witness signature + supply-tier price for a claim (the on-chain burn before
|
|
405
|
+
// key reveal). `signature` is the user's "Claim: <tokenId>" wallet signature.
|
|
406
|
+
async requestRemoteClaimSignature(web3: any, tokenId: string, signature: string, callback: any = null) {
|
|
407
|
+
if (callback) { callback('requesting Remote Claim signature')}
|
|
408
|
+
const chainId = await web3.eth.getChainId();
|
|
409
|
+
let url = `${this.baseUrl}/claim-curated`;
|
|
410
|
+
let remoteClaimResponse = await fetchData(url, this.apiKey, 'POST', {tokenId: tokenId, signature: signature, chainId: chainId.toString()});
|
|
411
|
+
if (remoteClaimResponse.error || remoteClaimResponse.err) {
|
|
412
|
+
throw new Error(remoteClaimResponse.error || remoteClaimResponse.msg || 'Failed to get claim signature')
|
|
413
|
+
}
|
|
414
|
+
if (callback) { callback(`remote Claim signature`, remoteClaimResponse)}
|
|
415
|
+
return remoteClaimResponse
|
|
416
|
+
}
|
|
417
|
+
|
|
404
418
|
// ** Bulk Mint **
|
|
405
419
|
//
|
|
406
420
|
// Builds the deterministic message a user signs to authorize a bulk curated
|
|
@@ -567,25 +581,34 @@ class EmblemVaultSDK {
|
|
|
567
581
|
|
|
568
582
|
|
|
569
583
|
async performBurn(web3: any, tokenId: any, callback: any = null) {
|
|
570
|
-
let metadata: any = await this.fetchMetadata(tokenId);
|
|
571
|
-
let targetContract: any = await this.fetchCuratedContractByName(metadata.targetContract.name);
|
|
572
584
|
if (callback) { callback('performing Burn')}
|
|
573
585
|
const accounts = await web3.eth.getAccounts();
|
|
574
|
-
const chainId = await web3.eth.getChainId();
|
|
575
586
|
let handlerContract = await getHandlerContract(web3);
|
|
576
|
-
|
|
577
|
-
//
|
|
587
|
+
|
|
588
|
+
// The handler no longer has a free claim(address,uint256); claiming requires
|
|
589
|
+
// a witness-signed price via claimWithSignedPrice. Get the user's "Claim:"
|
|
590
|
+
// signature, then the server-signed price for this asset (supply tier), then
|
|
591
|
+
// call claimWithSignedPrice with the server-derived on-chain tokenId + payment.
|
|
592
|
+
const claimSig = await this.requestLocalClaimSignature(web3, tokenId, null, callback);
|
|
593
|
+
const remote = await this.requestRemoteClaimSignature(web3, tokenId, claimSig, callback);
|
|
594
|
+
|
|
595
|
+
const price = remote._price;
|
|
596
|
+
const isEth = remote._payment === '0x0000000000000000000000000000000000000000';
|
|
597
|
+
|
|
578
598
|
const gasPrice = await web3.eth.getGasPrice();
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
599
|
+
let createdTxObject = handlerContract.methods.claimWithSignedPrice(
|
|
600
|
+
remote._nftAddress,
|
|
601
|
+
remote._tokenId,
|
|
602
|
+
remote._payment,
|
|
603
|
+
price,
|
|
604
|
+
remote._nonce,
|
|
605
|
+
remote._signature
|
|
606
|
+
);
|
|
607
|
+
const sendOpts: any = { from: accounts[0], gasPrice, value: isEth ? price : '0' };
|
|
608
|
+
sendOpts.gas = await createdTxObject.estimateGas(sendOpts);
|
|
609
|
+
|
|
610
|
+
let burnResponse = await createdTxObject.send(sendOpts)
|
|
611
|
+
.on('transactionHash', (hash: any) => {
|
|
589
612
|
if (callback) callback(`Transaction submitted. Hash`, hash);
|
|
590
613
|
})
|
|
591
614
|
.on('confirmation', (confirmationNumber: any, receipt: any) => {
|
|
@@ -594,11 +617,74 @@ class EmblemVaultSDK {
|
|
|
594
617
|
.on('error', (error: { message: any; }) => {
|
|
595
618
|
if (callback) callback(`Transaction Error`, error.message );
|
|
596
619
|
});
|
|
597
|
-
|
|
620
|
+
|
|
598
621
|
if (callback) { callback('Burn Complete')}
|
|
599
622
|
return burnResponse;
|
|
600
623
|
}
|
|
601
|
-
|
|
624
|
+
|
|
625
|
+
// Wallet signature authorizing a batch claim. Must match the server's expected
|
|
626
|
+
// message: "Claim: <sorted tokenIds joined by ','>" (order-independent).
|
|
627
|
+
async requestLocalBatchClaimSignature(web3: any, tokenIds: string[], callback: any = null) {
|
|
628
|
+
if (callback) { callback('requesting User Batch Claim Signature') }
|
|
629
|
+
const sorted = [...tokenIds.map(String)].sort().join(',');
|
|
630
|
+
const message = `Claim: ${sorted}`;
|
|
631
|
+
const accounts = await web3.eth.getAccounts();
|
|
632
|
+
const signature = await web3.eth.personal.sign(message, accounts[0], '');
|
|
633
|
+
return signature;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Fetch the batch witness signature + summed supply-tier price for several vaults.
|
|
637
|
+
async requestRemoteBatchClaimSignature(web3: any, tokenIds: string[], signature: string, callback: any = null) {
|
|
638
|
+
if (callback) { callback('requesting Remote Batch Claim signature') }
|
|
639
|
+
const chainId = await web3.eth.getChainId();
|
|
640
|
+
let url = `${this.baseUrl}/claim-curated-bulk`;
|
|
641
|
+
let remote = await fetchData(url, this.apiKey, 'POST', { tokenIds, signature, chainId: chainId.toString() });
|
|
642
|
+
if (remote.error || remote.err || remote.success === false) {
|
|
643
|
+
throw new Error(remote.error || remote.msg || 'Failed to get batch claim signature');
|
|
644
|
+
}
|
|
645
|
+
return remote;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Burn several vaults in one tx via batchClaimWithSignedPrice. One wallet
|
|
649
|
+
// signature + one witness signature + summed supply-tier price for the batch.
|
|
650
|
+
async performBatchBurn(web3: any, tokenIds: string[], callback: any = null) {
|
|
651
|
+
if (callback) { callback('performing Batch Burn') }
|
|
652
|
+
const accounts = await web3.eth.getAccounts();
|
|
653
|
+
let handlerContract = await getHandlerContract(web3);
|
|
654
|
+
|
|
655
|
+
const claimSig = await this.requestLocalBatchClaimSignature(web3, tokenIds, callback);
|
|
656
|
+
const remote = await this.requestRemoteBatchClaimSignature(web3, tokenIds, claimSig, callback);
|
|
657
|
+
|
|
658
|
+
const price = remote._price;
|
|
659
|
+
const isEth = remote._payment === '0x0000000000000000000000000000000000000000';
|
|
660
|
+
const value = isEth ? price : '0';
|
|
661
|
+
|
|
662
|
+
const gasPrice = await web3.eth.getGasPrice();
|
|
663
|
+
let createdTxObject = handlerContract.methods.batchClaimWithSignedPrice(
|
|
664
|
+
remote._nftAddresses,
|
|
665
|
+
remote._tokenIds,
|
|
666
|
+
remote._payment,
|
|
667
|
+
price,
|
|
668
|
+
remote._nonce,
|
|
669
|
+
remote._signature
|
|
670
|
+
);
|
|
671
|
+
const gas = await createdTxObject.estimateGas({ from: accounts[0], value });
|
|
672
|
+
|
|
673
|
+
let burnResponse = await createdTxObject.send({ from: accounts[0], value, gasPrice, gas })
|
|
674
|
+
.on('transactionHash', (hash: any) => {
|
|
675
|
+
if (callback) callback(`Transaction submitted. Hash`, hash);
|
|
676
|
+
})
|
|
677
|
+
.on('confirmation', (confirmationNumber: any, receipt: any) => {
|
|
678
|
+
if (callback) callback(`Batch Burn Complete. Confirmation Number`, confirmationNumber);
|
|
679
|
+
})
|
|
680
|
+
.on('error', (error: { message: any; }) => {
|
|
681
|
+
if (callback) callback(`Transaction Error`, error.message);
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
if (callback) { callback('Batch Burn Complete') }
|
|
685
|
+
return burnResponse;
|
|
686
|
+
}
|
|
687
|
+
|
|
602
688
|
|
|
603
689
|
async contentTypeReport(url: string) {
|
|
604
690
|
return await checkContentType(url)
|
|
@@ -699,6 +785,18 @@ class EmblemVaultSDK {
|
|
|
699
785
|
return performClaimEvm(this.getSdkContext(), client, tokenId, chainId as number, metadata, claimIdentifier, vaultIsV2, needsOnChainUnvault, callback);
|
|
700
786
|
}
|
|
701
787
|
|
|
788
|
+
// Client-path batch claim: burn several vaults in one tx (Step 1 only). Reveal
|
|
789
|
+
// each vault's keys afterward with performClaimChainWithClient (skips Step 1).
|
|
790
|
+
async performBatchBurnWithClient(
|
|
791
|
+
client: EmblemVaultClient,
|
|
792
|
+
tokenIds: string[],
|
|
793
|
+
chainId: number | 'solana' = ETHEREUM_MAINNET_CHAIN_ID,
|
|
794
|
+
callback?: ProgressCallback
|
|
795
|
+
): Promise<{ txHash: string }> {
|
|
796
|
+
getChainConfig(chainId);
|
|
797
|
+
return performBatchClaimEvm(this.getSdkContext(), client, tokenIds, chainId as number, callback);
|
|
798
|
+
}
|
|
799
|
+
|
|
702
800
|
async deleteVaultWithClient(
|
|
703
801
|
client: EmblemVaultClient,
|
|
704
802
|
tokenId: string,
|
|
@@ -2,3 +2,6 @@ import type { EmblemVaultClient, ProgressCallback, MintResult, ClaimResult, Meta
|
|
|
2
2
|
export declare function performMintEvm(ctx: SdkContext, client: EmblemVaultClient, tokenId: string, chainId: number, callback?: ProgressCallback): Promise<MintResult>;
|
|
3
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
4
|
export declare function deleteVaultEvm(client: EmblemVaultClient, tokenId: string, chainId: number, callback?: ProgressCallback): Promise<boolean>;
|
|
5
|
+
export declare function performBatchClaimEvm(ctx: SdkContext, client: EmblemVaultClient, tokenIds: string[], chainId: number, callback?: ProgressCallback): Promise<{
|
|
6
|
+
txHash: string;
|
|
7
|
+
}>;
|
package/types/index.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ declare class EmblemVaultSDK {
|
|
|
52
52
|
requestLocalMintSignature(web3: any, tokenId: string, callback?: any): Promise<any>;
|
|
53
53
|
requestLocalClaimSignature(web3: any, tokenId: string, serialNumber: any, callback?: any): Promise<any>;
|
|
54
54
|
requestRemoteMintSignature(web3: any, tokenId: string, signature: string, callback?: any): Promise<any>;
|
|
55
|
+
requestRemoteClaimSignature(web3: any, tokenId: string, signature: string, callback?: any): Promise<any>;
|
|
55
56
|
generateBulkMintMessage(tokenIds: string[]): string;
|
|
56
57
|
isV2Contract(metadata: any, chainId: number): boolean;
|
|
57
58
|
requestBulkMintSignature(request: BulkMintRequest, callback?: any): Promise<BulkMintResponse>;
|
|
@@ -64,6 +65,9 @@ declare class EmblemVaultSDK {
|
|
|
64
65
|
getQuote(web3: any, amount: number, callback?: any): Promise<BigNumber>;
|
|
65
66
|
performMint(web3: any, quote: any, remoteMintSig: any, callback?: any): Promise<any>;
|
|
66
67
|
performBurn(web3: any, tokenId: any, callback?: any): Promise<any>;
|
|
68
|
+
requestLocalBatchClaimSignature(web3: any, tokenIds: string[], callback?: any): Promise<any>;
|
|
69
|
+
requestRemoteBatchClaimSignature(web3: any, tokenIds: string[], signature: string, callback?: any): Promise<any>;
|
|
70
|
+
performBatchBurn(web3: any, tokenIds: string[], callback?: any): Promise<any>;
|
|
67
71
|
contentTypeReport(url: string): Promise<unknown>;
|
|
68
72
|
legacyBalanceFromContractByAddress(web3: any, address: string): Promise<number[]>;
|
|
69
73
|
refreshLegacyOwnership(web3: any, address: string): Promise<void>;
|
|
@@ -72,6 +76,9 @@ declare class EmblemVaultSDK {
|
|
|
72
76
|
private getSdkContext;
|
|
73
77
|
performMintChainWithClient(client: EmblemVaultClient, tokenId: string, chainId?: number | 'solana', callback?: ProgressCallback): Promise<MintResult>;
|
|
74
78
|
performClaimChainWithClient(client: EmblemVaultClient, tokenId: string, chainId?: number | 'solana', callback?: ProgressCallback): Promise<ClaimResult>;
|
|
79
|
+
performBatchBurnWithClient(client: EmblemVaultClient, tokenIds: string[], chainId?: number | 'solana', callback?: ProgressCallback): Promise<{
|
|
80
|
+
txHash: string;
|
|
81
|
+
}>;
|
|
75
82
|
deleteVaultWithClient(client: EmblemVaultClient, tokenId: string, chainId?: number | 'solana', callback?: ProgressCallback): Promise<boolean>;
|
|
76
83
|
sweepVaultUsingPhrase(phrase: string, satsPerByte?: number, broadcast?: boolean): Promise<unknown>;
|
|
77
84
|
}
|