@hashgraphonline/hashinal-wc 1.0.86 → 1.0.88
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/README.md +109 -0
- package/dist/es/hashinal-wc.es.js +189 -5
- package/dist/es/hashinal-wc.es.js.map +1 -1
- package/dist/es/index.d.ts +13 -3
- package/dist/es/types.d.ts +75 -2
- package/dist/index.d.ts +13 -3
- package/dist/types.d.ts +75 -2
- package/dist/umd/hashinal-wc.umd.js +1 -1
- package/dist/umd/hashinal-wc.umd.js.map +1 -1
- package/dist/umd/index.d.ts +13 -3
- package/dist/umd/types.d.ts +75 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,10 @@ This SDK provides a simple interface for interacting with the Hedera Hashgraph u
|
|
|
18
18
|
- Dissociate tokens from accounts
|
|
19
19
|
- Update account properties
|
|
20
20
|
- Approve token allowances
|
|
21
|
+
- Get transaction details by transaction ID or timestamp from the mirror node
|
|
22
|
+
- Get account NFTs with optional filtering by token ID
|
|
23
|
+
- Validate NFT ownership by serial number and token ID
|
|
24
|
+
- Make read-only calls to smart contracts on the mirror node
|
|
21
25
|
|
|
22
26
|
## Installation
|
|
23
27
|
|
|
@@ -518,6 +522,109 @@ const tokens = await sdk.getAccountTokens(accountId);
|
|
|
518
522
|
console.log('Account tokens:', tokens);
|
|
519
523
|
```
|
|
520
524
|
|
|
525
|
+
### `getTransaction(transactionId: string)`
|
|
526
|
+
|
|
527
|
+
Retrieves transaction details by transaction ID from the mirror node.
|
|
528
|
+
|
|
529
|
+
UMD Example:
|
|
530
|
+
|
|
531
|
+
```javascript
|
|
532
|
+
const transactionId = "0.0.123456@1234567890.000000000";
|
|
533
|
+
const transaction = await window.HashinalsWalletConnectSDK.getTransaction(transactionId);
|
|
534
|
+
console.log(transaction);
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
ESM Example:
|
|
538
|
+
|
|
539
|
+
```javascript
|
|
540
|
+
const transaction = await sdk.getTransaction(transactionId);
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### `getTransactionByTimestamp(timestamp: string)`
|
|
544
|
+
|
|
545
|
+
Retrieves transaction details by consensus timestamp from the mirror node.
|
|
546
|
+
|
|
547
|
+
UMD Example:
|
|
548
|
+
|
|
549
|
+
```javascript
|
|
550
|
+
const timestamp = "1234567890.000000000";
|
|
551
|
+
const transaction = await window.HashinalsWalletConnectSDK.getTransactionByTimestamp(timestamp);
|
|
552
|
+
console.log(transaction);
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
ESM Example:
|
|
556
|
+
|
|
557
|
+
```javascript
|
|
558
|
+
const transaction = await sdk.getTransactionByTimestamp(timestamp);
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### `getAccountNFTs(accountId: string, tokenId?: string)`
|
|
562
|
+
|
|
563
|
+
Retrieves all NFTs owned by an account, with optional filtering by token ID.
|
|
564
|
+
|
|
565
|
+
UMD Example:
|
|
566
|
+
|
|
567
|
+
```javascript
|
|
568
|
+
const accountId = "0.0.123456";
|
|
569
|
+
const nfts = await window.HashinalsWalletConnectSDK.getAccountNFTs(accountId);
|
|
570
|
+
console.log(nfts);
|
|
571
|
+
|
|
572
|
+
// With token filter
|
|
573
|
+
const tokenId = "0.0.789012";
|
|
574
|
+
const filteredNfts = await window.HashinalsWalletConnectSDK.getAccountNFTs(accountId, tokenId);
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
ESM Example:
|
|
578
|
+
|
|
579
|
+
```javascript
|
|
580
|
+
const nfts = await sdk.getAccountNFTs(accountId);
|
|
581
|
+
const filteredNfts = await sdk.getAccountNFTs(accountId, tokenId);
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### `validateNFTOwnership(serialNumber: string, accountId: string, tokenId: string)`
|
|
585
|
+
|
|
586
|
+
Validates if an account owns a specific NFT by serial number and token ID.
|
|
587
|
+
|
|
588
|
+
UMD Example:
|
|
589
|
+
|
|
590
|
+
```javascript
|
|
591
|
+
const serialNumber = "1";
|
|
592
|
+
const accountId = "0.0.123456";
|
|
593
|
+
const tokenId = "0.0.789012";
|
|
594
|
+
const nft = await window.HashinalsWalletConnectSDK.validateNFTOwnership(serialNumber, accountId, tokenId);
|
|
595
|
+
console.log(nft ? "Account owns this NFT" : "Account does not own this NFT");
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
ESM Example:
|
|
599
|
+
|
|
600
|
+
```javascript
|
|
601
|
+
const nft = await sdk.validateNFTOwnership(serialNumber, accountId, tokenId);
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
### `readSmartContract(data: string, fromAccount: AccountId, contractId: ContractId, estimate?: boolean, value?: number)`
|
|
605
|
+
|
|
606
|
+
Makes a read-only call to a smart contract on the mirror node.
|
|
607
|
+
|
|
608
|
+
UMD Example:
|
|
609
|
+
|
|
610
|
+
```javascript
|
|
611
|
+
const data = "0x..."; // Contract call data
|
|
612
|
+
const fromAccount = window.HashgraphSDK.AccountId.fromString("0.0.123456");
|
|
613
|
+
const contractId = window.HashgraphSDK.ContractId.fromString("0.0.789012");
|
|
614
|
+
const result = await window.HashinalsWalletConnectSDK.readSmartContract(data, fromAccount, contractId);
|
|
615
|
+
console.log(result);
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
ESM Example:
|
|
619
|
+
|
|
620
|
+
```javascript
|
|
621
|
+
import { AccountId, ContractId } from '@hashgraph/sdk';
|
|
622
|
+
|
|
623
|
+
const fromAccount = AccountId.fromString("0.0.123456");
|
|
624
|
+
const contractId = ContractId.fromString("0.0.789012");
|
|
625
|
+
const result = await sdk.readSmartContract(data, fromAccount, contractId);
|
|
626
|
+
```
|
|
627
|
+
|
|
521
628
|
## Versions and Topic IDs
|
|
522
629
|
|
|
523
630
|
Version 1.0.58 and onward correlate with the NPM Package version.
|
|
@@ -532,6 +639,8 @@ Version 1.0.58 and onward correlate with the NPM Package version.
|
|
|
532
639
|
| v1.0.71 | 0.0.7337015 | UMD |
|
|
533
640
|
| v1.0.79 | 0.0.7473819 | UMD |
|
|
534
641
|
| v1.0.82 | 0.0.7522981 | UMD |
|
|
642
|
+
| v1.0.86 | 0.0.7770334 | UMD |
|
|
643
|
+
| v1.0.88 | 0.0.7797532 | UMD |
|
|
535
644
|
|
|
536
645
|
## Contributing
|
|
537
646
|
|
|
@@ -1810,13 +1810,15 @@ var Result = /* @__PURE__ */ ((Result2) => {
|
|
|
1810
1810
|
return Result2;
|
|
1811
1811
|
})(Result || {});
|
|
1812
1812
|
class HashinalsWalletConnectSDK {
|
|
1813
|
-
get dAppConnector() {
|
|
1814
|
-
return HashinalsWalletConnectSDK.dAppConnectorInstance;
|
|
1815
|
-
}
|
|
1816
1813
|
constructor(logger, network) {
|
|
1814
|
+
this.extensionCheckInterval = null;
|
|
1815
|
+
this.hasCalledExtensionCallback = false;
|
|
1817
1816
|
this.logger = logger || new DefaultLogger();
|
|
1818
1817
|
this.network = network || LedgerId.MAINNET;
|
|
1819
1818
|
}
|
|
1819
|
+
get dAppConnector() {
|
|
1820
|
+
return HashinalsWalletConnectSDK.dAppConnectorInstance;
|
|
1821
|
+
}
|
|
1820
1822
|
static getInstance(logger, network) {
|
|
1821
1823
|
let instance = HashinalsWalletConnectSDK == null ? void 0 : HashinalsWalletConnectSDK.instance;
|
|
1822
1824
|
if (!instance) {
|
|
@@ -2235,12 +2237,13 @@ class HashinalsWalletConnectSDK {
|
|
|
2235
2237
|
return false;
|
|
2236
2238
|
}
|
|
2237
2239
|
}
|
|
2238
|
-
async initAccount(PROJECT_ID, APP_METADATA) {
|
|
2240
|
+
async initAccount(PROJECT_ID, APP_METADATA, networkOverride, onSessionIframeCreated = () => {
|
|
2241
|
+
}) {
|
|
2239
2242
|
const { accountId: savedAccountId, network: savedNetwork } = this.loadConnectionInfo();
|
|
2240
2243
|
if (savedAccountId && savedNetwork) {
|
|
2241
2244
|
try {
|
|
2242
2245
|
const network = savedNetwork === "mainnet" ? LedgerId.MAINNET : LedgerId.TESTNET;
|
|
2243
|
-
await this.init(PROJECT_ID, APP_METADATA, network);
|
|
2246
|
+
await this.init(PROJECT_ID, APP_METADATA, network, onSessionIframeCreated);
|
|
2244
2247
|
const balance = await this.getAccountBalance();
|
|
2245
2248
|
return {
|
|
2246
2249
|
accountId: savedAccountId,
|
|
@@ -2251,9 +2254,70 @@ class HashinalsWalletConnectSDK {
|
|
|
2251
2254
|
this.saveConnectionInfo(void 0, void 0);
|
|
2252
2255
|
return null;
|
|
2253
2256
|
}
|
|
2257
|
+
} else if (networkOverride) {
|
|
2258
|
+
try {
|
|
2259
|
+
this.logger.info("initializing normally through override.", networkOverride);
|
|
2260
|
+
await this.init(PROJECT_ID, APP_METADATA, networkOverride, onSessionIframeCreated);
|
|
2261
|
+
this.logger.info("initialized", networkOverride);
|
|
2262
|
+
await this.connectViaDappBrowser();
|
|
2263
|
+
this.logger.info("connected via dapp browser");
|
|
2264
|
+
} catch (error) {
|
|
2265
|
+
this.logger.error("Failed to fallback connect:", error);
|
|
2266
|
+
this.saveConnectionInfo(void 0, void 0);
|
|
2267
|
+
return null;
|
|
2268
|
+
}
|
|
2254
2269
|
}
|
|
2255
2270
|
return null;
|
|
2256
2271
|
}
|
|
2272
|
+
subscribeToExtensions(callback) {
|
|
2273
|
+
if (this.extensionCheckInterval) {
|
|
2274
|
+
clearInterval(this.extensionCheckInterval);
|
|
2275
|
+
}
|
|
2276
|
+
this.hasCalledExtensionCallback = false;
|
|
2277
|
+
this.extensionCheckInterval = setInterval(() => {
|
|
2278
|
+
var _a;
|
|
2279
|
+
const extensions = ((_a = this.dAppConnector) == null ? void 0 : _a.extensions) || [];
|
|
2280
|
+
const availableExtension = extensions.find((ext) => ext.availableInIframe);
|
|
2281
|
+
if (availableExtension && !this.hasCalledExtensionCallback) {
|
|
2282
|
+
this.hasCalledExtensionCallback = true;
|
|
2283
|
+
callback(availableExtension);
|
|
2284
|
+
if (this.extensionCheckInterval) {
|
|
2285
|
+
clearInterval(this.extensionCheckInterval);
|
|
2286
|
+
this.extensionCheckInterval = null;
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
}, 1e3);
|
|
2290
|
+
return () => {
|
|
2291
|
+
if (this.extensionCheckInterval) {
|
|
2292
|
+
clearInterval(this.extensionCheckInterval);
|
|
2293
|
+
this.extensionCheckInterval = null;
|
|
2294
|
+
}
|
|
2295
|
+
this.hasCalledExtensionCallback = false;
|
|
2296
|
+
};
|
|
2297
|
+
}
|
|
2298
|
+
async connectViaDappBrowser() {
|
|
2299
|
+
const extensions = this.dAppConnector.extensions || [];
|
|
2300
|
+
const extension = extensions.find((ext) => {
|
|
2301
|
+
this.logger.info("Checking extension", ext);
|
|
2302
|
+
return ext.availableInIframe;
|
|
2303
|
+
});
|
|
2304
|
+
this.logger.info("extensions are", extensions, extension);
|
|
2305
|
+
if (extension) {
|
|
2306
|
+
await this.connectToExtension(extension);
|
|
2307
|
+
} else {
|
|
2308
|
+
this.subscribeToExtensions(async (newExtension) => {
|
|
2309
|
+
await this.connectToExtension(newExtension);
|
|
2310
|
+
});
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
async connectToExtension(extension) {
|
|
2314
|
+
this.logger.info("found extension, connecting to iframe.", extension);
|
|
2315
|
+
const session = await this.dAppConnector.connectExtension(extension.id);
|
|
2316
|
+
const onSessionIframeCreated = this.dAppConnector.onSessionIframeCreated;
|
|
2317
|
+
if (onSessionIframeCreated) {
|
|
2318
|
+
onSessionIframeCreated(session);
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2257
2321
|
ensureInitialized() {
|
|
2258
2322
|
if (!this.dAppConnector) {
|
|
2259
2323
|
throw new Error("SDK not initialized. Call init() first.");
|
|
@@ -2371,6 +2435,126 @@ class HashinalsWalletConnectSDK {
|
|
|
2371
2435
|
throw error;
|
|
2372
2436
|
}
|
|
2373
2437
|
}
|
|
2438
|
+
async getTransaction(transactionId) {
|
|
2439
|
+
try {
|
|
2440
|
+
const networkPrefix = this.getNetworkPrefix();
|
|
2441
|
+
const url = `https://${networkPrefix}.mirrornode.hedera.com/api/v1/transactions/${transactionId}`;
|
|
2442
|
+
this.logger.debug("Fetching transaction", url);
|
|
2443
|
+
const request = await fetchWithRetry()(url);
|
|
2444
|
+
if (!request.ok) {
|
|
2445
|
+
throw new Error(`Failed to fetch transaction: ${request.status}`);
|
|
2446
|
+
}
|
|
2447
|
+
return await request.json();
|
|
2448
|
+
} catch (e) {
|
|
2449
|
+
this.logger.error("Failed to get transaction", e);
|
|
2450
|
+
return null;
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
async getTransactionByTimestamp(timestamp) {
|
|
2454
|
+
var _a;
|
|
2455
|
+
try {
|
|
2456
|
+
const networkPrefix = this.getNetworkPrefix();
|
|
2457
|
+
const url = `https://${networkPrefix}.mirrornode.hedera.com/api/v1/transactions?timestamp=${timestamp}`;
|
|
2458
|
+
this.logger.debug("Fetching transaction by timestamp", url);
|
|
2459
|
+
const request = await fetchWithRetry()(url);
|
|
2460
|
+
if (!request.ok) {
|
|
2461
|
+
throw new Error(
|
|
2462
|
+
`Failed to fetch transaction by timestamp: ${request.status}`
|
|
2463
|
+
);
|
|
2464
|
+
}
|
|
2465
|
+
const response = await request.json();
|
|
2466
|
+
const transaction = (_a = response == null ? void 0 : response.transactions) == null ? void 0 : _a[0];
|
|
2467
|
+
if (transaction) {
|
|
2468
|
+
return await this.getTransaction(transaction.transaction_id);
|
|
2469
|
+
}
|
|
2470
|
+
return null;
|
|
2471
|
+
} catch (e) {
|
|
2472
|
+
this.logger.error("Failed to get transaction by timestamp", e);
|
|
2473
|
+
return null;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
async getAccountNFTs(accountId, tokenId) {
|
|
2477
|
+
var _a, _b, _c;
|
|
2478
|
+
try {
|
|
2479
|
+
const networkPrefix = this.getNetworkPrefix();
|
|
2480
|
+
const tokenQuery = tokenId ? `&token.id=${tokenId}` : "";
|
|
2481
|
+
const url = `https://${networkPrefix}.mirrornode.hedera.com/api/v1/accounts/${accountId}/nfts?limit=200${tokenQuery}`;
|
|
2482
|
+
const request = await fetchWithRetry()(url);
|
|
2483
|
+
if (!request.ok) {
|
|
2484
|
+
throw new Error(`Failed to fetch NFTs for account: ${request.status}`);
|
|
2485
|
+
}
|
|
2486
|
+
const response = await request.json();
|
|
2487
|
+
let nextLink = ((_a = response == null ? void 0 : response.links) == null ? void 0 : _a.next) || null;
|
|
2488
|
+
let nfts = response.nfts;
|
|
2489
|
+
while (nextLink) {
|
|
2490
|
+
try {
|
|
2491
|
+
const nextRequest = await fetchWithRetry()(
|
|
2492
|
+
`https://${networkPrefix}.mirrornode.hedera.com${nextLink}`
|
|
2493
|
+
);
|
|
2494
|
+
if (!nextRequest.ok) {
|
|
2495
|
+
throw new Error(
|
|
2496
|
+
`Failed to fetch next page of NFTs: ${nextRequest.status}`
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2499
|
+
const nextResponse = await nextRequest.json();
|
|
2500
|
+
nfts = [...nfts, ...(nextResponse == null ? void 0 : nextResponse.nfts) || []];
|
|
2501
|
+
nextLink = ((_b = nextResponse == null ? void 0 : nextResponse.links) == null ? void 0 : _b.next) && nextLink !== ((_c = nextResponse == null ? void 0 : nextResponse.links) == null ? void 0 : _c.next) ? nextResponse.links.next : null;
|
|
2502
|
+
} catch (e) {
|
|
2503
|
+
this.logger.error("Failed to fetch next page of NFTs", e);
|
|
2504
|
+
break;
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
return nfts.map((nft) => {
|
|
2508
|
+
try {
|
|
2509
|
+
nft.token_uri = Buffer$1.from(nft.metadata, "base64").toString("ascii");
|
|
2510
|
+
} catch (e) {
|
|
2511
|
+
this.logger.error("Failed to decode NFT metadata", e);
|
|
2512
|
+
}
|
|
2513
|
+
return nft;
|
|
2514
|
+
});
|
|
2515
|
+
} catch (e) {
|
|
2516
|
+
this.logger.error("Failed to get account NFTs", e);
|
|
2517
|
+
return [];
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
async validateNFTOwnership(serialNumber, accountId, tokenId) {
|
|
2521
|
+
const userNFTs = await this.getAccountNFTs(accountId, tokenId);
|
|
2522
|
+
return userNFTs.find(
|
|
2523
|
+
(nft) => nft.token_id === tokenId && nft.serial_number.toString() === serialNumber
|
|
2524
|
+
) || null;
|
|
2525
|
+
}
|
|
2526
|
+
async readSmartContract(data, fromAccount, contractId, estimate = true, value = 0) {
|
|
2527
|
+
try {
|
|
2528
|
+
const networkPrefix = this.getNetworkPrefix();
|
|
2529
|
+
const body = {
|
|
2530
|
+
block: "latest",
|
|
2531
|
+
data,
|
|
2532
|
+
estimate,
|
|
2533
|
+
from: fromAccount.toSolidityAddress(),
|
|
2534
|
+
to: contractId.toSolidityAddress(),
|
|
2535
|
+
value
|
|
2536
|
+
};
|
|
2537
|
+
if (!estimate) {
|
|
2538
|
+
body.gas = 3e5;
|
|
2539
|
+
body.gasPrice = 1e8;
|
|
2540
|
+
}
|
|
2541
|
+
const url = `https://${networkPrefix}.mirrornode.hedera.com/api/v1/contracts/call`;
|
|
2542
|
+
const response = await fetchWithRetry()(url, {
|
|
2543
|
+
method: "POST",
|
|
2544
|
+
body: JSON.stringify(body),
|
|
2545
|
+
headers: {
|
|
2546
|
+
"Content-Type": "application/json"
|
|
2547
|
+
}
|
|
2548
|
+
});
|
|
2549
|
+
if (!response.ok) {
|
|
2550
|
+
throw new Error(`Failed to make contract call: ${response.status}`);
|
|
2551
|
+
}
|
|
2552
|
+
return await response.json();
|
|
2553
|
+
} catch (e) {
|
|
2554
|
+
this.logger.error("Failed to make contract call", e);
|
|
2555
|
+
return null;
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2374
2558
|
}
|
|
2375
2559
|
export {
|
|
2376
2560
|
HashgraphSDK,
|