Conversation
* fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] ## [1.5.4](v1.5.3...v1.5.4) (2025-06-17) ### Bug Fixes * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] ## [1.5.5](v1.5.4...v1.5.5) (2025-06-18) ### Bug Fixes * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
* fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] ## [1.5.4](v1.5.3...v1.5.4) (2025-06-17) ### Bug Fixes * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] ## [1.5.5](v1.5.4...v1.5.5) (2025-06-18) ### Bug Fixes * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * feat: add transfer holder function * feat: add transfer owners beneficiary * chore: tests cleanup * chore: tests cleanup * fix: remove console * fix: rever useendorement chain * fix: remove console * feat: add reject transfer functions * chore: trigger rebuild after rebase * chore(release): 1.5.4 [skip ci] * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * feat: add transfer holder function * feat: add transfer owners beneficiary * chore: tests cleanup * fix: remove console * fix: rever useendorement chain * feat: add reject transfer functions * chore: trigger rebuild after rebase * chore: trigger rebuild after rebase * feat: token registry return functions * feat: add mint function * fix: update fixes * fix: update tests * revert: revert changes --------- Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Ng Han Inn <43451336+nghaninn@users.noreply.github.com>
* feat: add ownerOf function * feat: add test cases * fix: update test cases for ownerof function * fix: update imports * fix: update imports
* feat: add ownerOf function * feat: add test cases * fix: update test cases for ownerof function * chore: add e2e test for transfer functions * chore: add e2e test for transfer functions * feat: add ownerOf function * feat: add test cases * fix: update test cases for ownerof function * chore: add e2e test for transfer functions * chore: add e2e test for transfer functions * fix: update mock tests * fix: update mock test fixtures * fix: update mock tests for mint and return * fix: update test script * fix: update imports * fix: update gitignore * fix: delete cache * fix: update imports
* chore: e2e tests for reject functions * fix: reject function ethers v6 compatible * fix: update imports * fix: mock test cases * fix: import fixed
* chore: e2e tests for reject functions * fix: reject function ethers v6 compatible * fix: update imports * fix: mock test cases * fix: static call fixes * chore: add e2e test cases * fix: update imports * fix: update imports * fix: tests * fix: mock functions * fix: change name * fix: update imports * fix: update src imports
* fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] ## [1.5.4](v1.5.3...v1.5.4) (2025-06-17) ### Bug Fixes * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] ## [1.5.5](v1.5.4...v1.5.5) (2025-06-18) ### Bug Fixes * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * feat: support passing titleEscrowAddress to fetchEndorsementChain (#80) Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> * chore(release): 1.6.0 [skip ci] ## [1.6.0](v1.5.5...v1.6.0) (2025-07-14) ### Features * support passing titleEscrowAddress to fetchEndorsementChain ([#80](#80)) ([aa7b4f0](aa7b4f0)) * feat: add astron v5 (#81) Co-authored-by: maxufeng <maxufeng@caict.ac.cn> * chore(release): 1.7.0 [skip ci] ## [1.7.0](v1.6.0...v1.7.0) (2025-07-15) ### Features * add astron v5 ([#81](#81)) ([0bebeae](0bebeae)) --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Ng Han Inn <43451336+nghaninn@users.noreply.github.com> Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> Co-authored-by: caict-develop-zhangbo <68949988+caict-develop-zhangbo@users.noreply.github.com> Co-authored-by: maxufeng <maxufeng@caict.ac.cn>
Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com>
## [1.6.0-alpha.4](v1.6.0-alpha.3...v1.6.0-alpha.4) (2025-07-23) ### Bug Fixes * trigger release ([#86](#86)) ([d2fb6fb](d2fb6fb)) ### Miscellaneous Chores * merge main into v1 ([#85](#85)) ([b81b422](b81b422)), closes [#72](#72) [#72](#72) [#73](#73) [#73](#73) [#80](#80) [#80](#80) [#81](#81) [#81](#81)
* fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] ## [1.5.4](v1.5.3...v1.5.4) (2025-06-17) ### Bug Fixes * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] ## [1.5.5](v1.5.4...v1.5.5) (2025-06-18) ### Bug Fixes * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * feat: support passing titleEscrowAddress to fetchEndorsementChain (#80) Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> * chore(release): 1.6.0 [skip ci] ## [1.6.0](v1.5.5...v1.6.0) (2025-07-14) ### Features * support passing titleEscrowAddress to fetchEndorsementChain ([#80](#80)) ([aa7b4f0](aa7b4f0)) * feat: add astron v5 (#81) Co-authored-by: maxufeng <maxufeng@caict.ac.cn> * chore(release): 1.7.0 [skip ci] ## [1.7.0](v1.6.0...v1.7.0) (2025-07-15) ### Features * add astron v5 ([#81](#81)) ([0bebeae](0bebeae)) * fix: update tradetrust-tt/tradetrust package (#87) * fix: update tradetrust-tt/tradetrust package * fix: update version * fix: update imports * chore(release): 1.7.1 [skip ci] ## [1.7.1](v1.7.0...v1.7.1) (2025-07-25) ### Bug Fixes * update tradetrust-tt/tradetrust package ([#87](#87)) ([e4f75a4](e4f75a4)) * fix: upgrade packages (#88) * chore(release): 1.7.2 [skip ci] ## [1.7.2](v1.7.1...v1.7.2) (2025-07-28) ### Bug Fixes * upgrade packages ([#88](#88)) ([0cc314e](0cc314e)) * fix: error message types (#89) * chore(release): 1.7.3 [skip ci] ## [1.7.3](v1.7.2...v1.7.3) (2025-07-28) ### Bug Fixes * error message types ([#89](#89)) ([d83bada](d83bada)) * fix: upgrade packages (#90) * chore(release): 1.7.4 [skip ci] ## [1.7.4](v1.7.3...v1.7.4) (2025-07-29) ### Bug Fixes * upgrade packages ([#90](#90)) ([758651d](758651d)) --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Ng Han Inn <43451336+nghaninn@users.noreply.github.com> Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> Co-authored-by: caict-develop-zhangbo <68949988+caict-develop-zhangbo@users.noreply.github.com> Co-authored-by: maxufeng <maxufeng@caict.ac.cn>
WalkthroughThis update introduces a comprehensive suite of token registry functions for Ethereum smart contract interaction, supporting both ethers.js v5 and v6 and multiple contract versions (v4 and v5). It adds new modules for minting, transferring, rejecting, returning, and querying tokens, with robust TypeScript typings and utilities. Extensive unit and end-to-end tests validate all functionalities, and configuration files are updated to support these enhancements. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App
participant TokenRegistryFunctions
participant EthersProvider
participant SmartContract
User->>App: Initiate token registry action (e.g., mint, transfer)
App->>TokenRegistryFunctions: Call function (e.g., mint, transferHolder)
TokenRegistryFunctions->>EthersProvider: Connect signer/provider
TokenRegistryFunctions->>SmartContract: Perform static call (pre-check)
SmartContract-->>TokenRegistryFunctions: Return pre-check result
TokenRegistryFunctions->>SmartContract: Send transaction (with params)
SmartContract-->>TokenRegistryFunctions: Emit transaction receipt/event
TokenRegistryFunctions-->>App: Return transaction result
App-->>User: Show result/status
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Possibly related PRs
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 29
🧹 Nitpick comments (19)
src/__tests__/token-registry-functions/mint.test.ts (1)
51-51: Remove commented code.Clean up the commented code to improve readability and maintainability.
const isV5TT = titleEscrowVersion === 'v5'; - // let mockContract = isV5TT ? mockV5TradeTrustTokenContract : mockV4TradeTrustTokenContract; const mockTxResponse = titleEscrowVersion === 'v5' ? 'v5_mint_tx_hash' : 'v4_mint_tx_hash';const mockBeneficiaryAddress = '0xBeneficiaryAddress'; const mockHolderAddress = '0xHolderAddress'; - // const titleEscrowAddress = isV5TT ? '0xv5contract' : '0xv4contract'; const mockTradeTrustTokenContract = isV5TTAlso applies to: 67-67
src/token-registry-functions/ownerOf.ts (1)
62-67: Simplify the return logic.The conditional return logic can be simplified since the contract type is already determined and the
ownerOfmethod signature is the same for both versions.- // Send the actual transaction - - if (isV5TT) { - return await (tradeTrustTokenContract as v5Contracts.TradeTrustToken).ownerOf(tokenId); - } else if (isV4TT) { - return await (tradeTrustTokenContract as v4Contracts.TradeTrustToken).ownerOf(tokenId); - } + // Query the owner of the token + return await tradeTrustTokenContract.ownerOf(tokenId);src/__tests__/token-registry-functions/rejectTransfers.test.ts (1)
56-61: Remove commented code.Clean up the commented code to improve readability.
if (ethersVersion === 'v5') { wallet = new WalletV5(PRIVATE_KEY, Provider as any) as ethersV5.Wallet; - // wallet = { - // ...wallet, - // address: '0xcurrent_holder', - // getChainId: vi.fn().mockResolvedValue(CHAIN_ID.mainnet as unknown as number), - // } as any; vi.spyOn(wallet, 'getChainId').mockResolvedValue(CHAIN_ID.mainnet as unknown as number); } else { wallet = new WalletV6(PRIVATE_KEY, Provider as any); vi.spyOn(Provider, 'getNetwork').mockResolvedValue({ chainId: CHAIN_ID.mainnet, } as unknown as Network); - // vi.spyOn(wallet, 'getAddress').mockResolvedValue('0xcurrent_holder'); }Also applies to: 67-67
src/__tests__/token-registry-functions/ownerOf.test.ts (2)
49-49: Remove commented code- // let mockContract = isV5TT ? mockV5TradeTrustTokenContract : mockV4TradeTrustTokenContract;
72-75: Remove commented afterEach block- - // afterEach(() => { - // vi.restoreAllMocks(); - // });src/token-registry-functions/mint.ts (2)
59-75: Consider improving type safetyThe code casts the signer to
anyon lines 66 and 73, which bypasses TypeScript's type checking.Consider using a type guard or conditional types to maintain type safety:
// Example approach type SignerUnion = Signer | SignerV6; const typedSigner = isV6EthersProvider(signer.provider) ? signer as SignerV6 : signer as Signer;
104-120: Consider simplifying the conditional logicThe function has two separate conditional blocks that could be combined since both conditions are mutually exclusive.
- if (isV5TT) { - return await tradeTrustTokenContract.mint( - beneficiaryAddress, - holderAddress, - tokenId, - encryptedRemarks, - txOptions, - ); - } else if (isV4TT) { - return await tradeTrustTokenContract.mint( - beneficiaryAddress, - holderAddress, - tokenId, - txOptions, - ); - } + const mintArgs = isV5TT + ? [beneficiaryAddress, holderAddress, tokenId, encryptedRemarks, txOptions] + : [beneficiaryAddress, holderAddress, tokenId, txOptions]; + + return await tradeTrustTokenContract.mint(...mintArgs);src/__tests__/token-registry-functions/returnToken.test.ts (1)
219-219: Remove commented debug code- // vi.spyOn(coreModule, 'encrypt').mockReturnValue(mockEncryptedRemarks.slice(2));src/__tests__/token-registry-functions/transfers.test.ts (1)
88-271: Consider refactoring to reduce test duplicationThe test suites for
transferHolder,transferBeneficiary,transferOwners, andnominatefollow nearly identical patterns. Consider extracting common test scenarios into shared test utilities.Example approach:
const createTransferTestSuite = ( functionName: string, transferFn: Function, getParams: (isV5: boolean) => any, getTxHash: (isV5: boolean) => string ) => { // Common test implementations };Would you like me to create a refactored version that reduces duplication while maintaining test coverage?
Also applies to: 273-447, 449-631, 633-803
src/__tests__/e2e/fixtures.ts (3)
23-36: Provider version detection relies on fragile implementation detailsThe current approach of detecting provider versions by checking internal properties like
_getConnection,getNetwork.length, andconnectionis fragile and may break with ethers.js updates. Consider using a more robust approach such as checking the constructor name or adding explicit version tracking.-export const getProviderVersion = (provider: any): 'v5' | 'v6' => { - // Check for v6-specific properties - if (provider._getConnection || provider.getNetwork?.length === 0) { - return 'v6'; - } - // Check for v5-specific properties - if (provider.getNetwork?.length === 1 || provider.connection) { - return 'v5'; - } - return 'v5'; // default fallback -}; +export const getProviderVersion = (provider: any): 'v5' | 'v6' => { + // Check constructor name first + const constructorName = provider.constructor.name; + if (constructorName.includes('JsonRpcProvider')) { + // For v6, check if it's from the ethersV6 module + if (provider instanceof JsonRpcProviderV6) { + return 'v6'; + } + // Otherwise assume v5 + return 'v5'; + } + + // Fallback to property checking if constructor name doesn't help + if (provider._getConnection || (provider.getNetwork && typeof provider.getNetwork === 'function' && provider.getNetwork.length === 0)) { + return 'v6'; + } + return 'v5'; +};
37-44: Misleading function name - returns real providers, not mocksThe function name
createMockHardhatProvidersuggests it creates mock providers, but it actually returns the real Hardhat providers created at the module level. Consider renaming to better reflect its purpose.-// Mock hardhat ethers provider for testing -export const createMockHardhatProvider = (version: 'v5' | 'v6' = 'v5') => { +// Get hardhat ethers provider for testing +export const getHardhatProvider = (version: 'v5' | 'v6' = 'v5') => { if (version === 'v6') { return providerV6; } return providerV5; };
104-123: Unnecessary async functions and incomplete funding implementation
- The functions are marked as
asyncbut don't perform any asynchronous operations.- The commented-out funding code suggests incomplete implementation.
-// Get multiple signers for ethers v5 (similar to hardhat getSigners) -export const getSignersV5 = async (count: number = 10): Promise<ethersV5.Wallet[]> => { +// Get multiple signers for ethers v5 (similar to hardhat getSigners) +export const getSignersV5 = (count: number = 10): ethersV5.Wallet[] => { const privateKeys = generateTestV5PrivateKeys(count); const wallets = privateKeys.map((key) => new ethersV5.Wallet(key, providerV5)); - - // Fund the wallets from Hardhat's pre-funded account - // await fundWalletsV5(wallets); - return wallets; }; -// Get multiple signers for ethers v6 (similar to hardhat getSigners) -export const getSignersV6 = async (count: number = 10): Promise<WalletV6[]> => { +// Get multiple signers for ethers v6 (similar to hardhat getSigners) +export const getSignersV6 = (count: number = 10): WalletV6[] => { const privateKeys = generateTestV6PrivateKeys(count); const wallets = privateKeys.map((key) => new WalletV6(key, providerV6)); - - // Fund the wallets from Hardhat's pre-funded account - // await fundWalletsV6Simple(wallets); - return wallets; };If wallet funding is needed, consider implementing it as a separate utility function that can be called when needed.
src/__tests__/e2e/token-registry-functions/rejectTransfer.e2e.test.ts (1)
366-367: Fragile error message assertionsThe tests assert exact error messages which makes them fragile to changes in error wording. Consider using partial matches or error codes instead.
- expect(error.message).to.include('ERC721: owner query for nonexistent token'); + expect(error.message.toLowerCase()).to.include('nonexistent token'); - expect(error.message).to.equal('Only Token Registry V5 is supported'); + expect(error.message).to.match(/only.*v5.*supported/i); - expect(error.message).to.equal( - 'Pre-check (callStatic) for rejectTransferHolder failed', - ); + expect(error.message).to.include('Pre-check'); + expect(error.message).to.include('rejectTransferHolder'); + expect(error.message).to.include('failed');Also applies to: 522-523, 546-547
src/__tests__/e2e/token-registry-functions/transfer.e2e.test.ts (2)
81-81: Remove or implement the commented resetNonceTracker callThis commented code suggests nonce tracking was considered but not implemented. Either implement proper nonce management or remove this comment to avoid confusion.
287-291: Consider conditional test registration instead of runtime skipWhile using
this.skip()works, consider conditionally registering the test for better test reporting and clarity.- it('should mint token with encrypted remarks (V5 only)', async function () { - // Skip this test for V4 as it doesn't support encrypted remarks - if (titleEscrowVersion === 'v4') { - console.log('Skipping encrypted remarks test for V4'); - this.skip(); - } + // Only register this test for V5 + if (titleEscrowVersion === 'v5') { + it('should mint token with encrypted remarks (V5 only)', async function () {src/token-registry-functions/returnToken.ts (2)
57-59: Remove commented codeRemove the commented code to maintain code cleanliness.
- // Connect V5 contract by default - // let titleEscrowContract: v5Contracts.TitleEscrow | v4Contracts.TitleEscrow = - // v5Contracts.TitleEscrow__factory.connect(titleEscrowAddress, signer);
86-104: Add explicit initialization to prevent potential undefined contractWhile the earlier version check should prevent this, the contract variable could theoretically be undefined.
const Contract = getEthersContractFromProvider(signer.provider); - // Connect V5 contract by default - let titleEscrowContract: ContractV5 | ContractV6; + let titleEscrowContract: ContractV5 | ContractV6 | undefined; if (isV5TT) { titleEscrowContract = new Contract( titleEscrowAddress, v5Contracts.TitleEscrow__factory.abi, // eslint-disable-next-line @typescript-eslint/no-explicit-any signer as any, ); } else if (isV4TT) { titleEscrowContract = new Contract( titleEscrowAddress, v4Contracts.TitleEscrow__factory.abi, // eslint-disable-next-line @typescript-eslint/no-explicit-any signer as any, ); } + + if (!titleEscrowContract) { + throw new Error('Failed to instantiate title escrow contract'); + }src/token-registry-functions/transfer.ts (2)
502-502: Remove duplicate commentThere's a duplicate "Check callStatic (dry run)" comment.
// Check callStatic (dry run) - // Check callStatic (dry run) try {
38-527: Consider refactoring to reduce code duplicationAll four transfer functions share nearly identical structure for version detection, contract instantiation, and transaction execution. This violates DRY principles.
Consider creating a common helper function that handles:
- Title escrow address resolution
- Version detection
- Contract instantiation
- CallStatic pre-check
- Transaction execution
This would reduce the codebase by ~60% and make maintenance easier. Each function would then only need to specify its unique parameters and method name.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (27)
.gitignore(1 hunks)hardhat.config.ts(1 hunks)package.json(3 hunks)src/__tests__/core/verify.test.ts(1 hunks)src/__tests__/e2e/fixtures.ts(1 hunks)src/__tests__/e2e/token-registry-functions/rejectTransfer.e2e.test.ts(1 hunks)src/__tests__/e2e/token-registry-functions/returnToken.e2e.test.ts(1 hunks)src/__tests__/e2e/token-registry-functions/transfer.e2e.test.ts(1 hunks)src/__tests__/e2e/utils.ts(1 hunks)src/__tests__/token-registry-functions/fixtures.ts(1 hunks)src/__tests__/token-registry-functions/mint.test.ts(1 hunks)src/__tests__/token-registry-functions/ownerOf.test.ts(1 hunks)src/__tests__/token-registry-functions/rejectTransfers.test.ts(1 hunks)src/__tests__/token-registry-functions/returnToken.test.ts(1 hunks)src/__tests__/token-registry-functions/transfers.test.ts(1 hunks)src/core/endorsement-chain/useEndorsementChain.ts(1 hunks)src/index.ts(1 hunks)src/token-registry-functions/index.ts(1 hunks)src/token-registry-functions/mint.ts(1 hunks)src/token-registry-functions/ownerOf.ts(1 hunks)src/token-registry-functions/rejectTransfers.ts(1 hunks)src/token-registry-functions/returnToken.ts(1 hunks)src/token-registry-functions/transfer.ts(1 hunks)src/token-registry-functions/types.ts(1 hunks)src/token-registry-functions/utils.ts(1 hunks)tsconfig.json(1 hunks)vitest.config.ts(3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/core/endorsement-chain/useEndorsementChain.ts (1)
src/utils/ethers/index.ts (1)
getEthersContractFromProvider(24-28)
src/__tests__/token-registry-functions/ownerOf.test.ts (2)
src/token-registry-functions/types.ts (1)
ProviderInfo(85-89)src/__tests__/token-registry-functions/fixtures.ts (6)
providerV5(300-300)providerV6(301-301)PRIVATE_KEY(298-298)MOCK_V5_ADDRESS(6-6)MOCK_V4_ADDRESS(7-7)MOCK_OWNER_ADDRESS(8-8)
🔇 Additional comments (24)
.gitignore (1)
8-8: LGTM! Clean cache directory exclusion.The addition of
cache/to the gitignore is appropriate for development tooling and testing infrastructure, preventing transient cache files from being committed.src/__tests__/core/verify.test.ts (1)
11-11: LGTM! Import path updated for consistency.The change from absolute to relative import path aligns with the new path mapping configuration in
tsconfig.jsonand maintains consistency with other imports in the file.tsconfig.json (2)
8-8: LGTM! Proper types for testing frameworks.Adding
"vitest/globals"and"mocha"to the types array provides appropriate TypeScript support for the testing frameworks used in the new test suites.
11-13: LGTM! Clean path mapping configuration.The
"src/*": ["./src/*"]path mapping enables cleaner import paths and aligns with the module resolution alias configured invitest.config.ts.vitest.config.ts (3)
7-11: LGTM! Consistent module resolution alias.The alias configuration
'src/': new URL('./src/', import.meta.url).pathnamealigns with the path mapping intsconfig.jsonand ensures consistent module resolution across the testing environment.
23-23: LGTM! Global test functions enabled.Setting
globals: trueenables global test functions (describe, it, expect) which matches the testing style used in the test files.
34-34: LGTM! Proper separation of test types.Excluding
'src/__tests__/e2e/**'from regular test runs is a good practice, allowing separation of fast unit tests from slower end-to-end tests.src/index.ts (1)
23-23: Approve wildcard export of token registry functionsThe new
export * from './token-registry-functions';insrc/index.tscorrectly exposes the token registry API at the main entry point. Verification confirms thatsrc/token-registry-functions/index.tsexists and re-exports the expected functions (transfer,rejectTransfers,returnToken,mint, andownerOf).• File:
src/index.ts
Line: 23 —export * from './token-registry-functions';
• Verified exports insrc/token-registry-functions/index.tssrc/token-registry-functions/index.ts (1)
1-5: LGTM! Clean barrel export pattern.The index file properly aggregates all token registry function exports using a standard barrel export pattern. This provides a clean, centralized entry point for consumers of the token registry functions.
hardhat.config.ts (1)
1-34: LGTM! Well-configured Hardhat setup.The configuration is properly structured with:
- Appropriate Solidity version (0.8.20) and optimization settings
- Reasonable network configurations for local development
- Extended Mocha timeout (60s) suitable for e2e blockchain tests
- Correct plugin imports for TypeScript and testing support
src/__tests__/token-registry-functions/mint.test.ts (1)
80-93: LGTM! Comprehensive test setup.The
beforeEachsetup properly mocks all necessary dependencies and handles both ethers versions correctly. The interface support and encryption mocks are appropriately configured.src/token-registry-functions/ownerOf.ts (1)
8-18: LGTM! Excellent documentation.The JSDoc documentation is comprehensive and clearly explains the function's purpose, parameters, return value, and error conditions.
src/__tests__/token-registry-functions/rejectTransfers.test.ts (1)
77-203: LGTM! Comprehensive test coverage.The test suites for all three reject transfer functions (
rejectTransferHolder,rejectTransferBeneficiary,rejectTransferOwners) are well-structured with excellent coverage of:
- Success scenarios with and without remarks
- Error handling for missing parameters
- Provider validation
- Version compatibility checks
- Static call failure handling
The consistent test patterns across all three functions ensure reliable validation of the reject transfer functionality.
Also applies to: 205-330, 332-458
src/__tests__/token-registry-functions/fixtures.ts (2)
19-28: LGTM!The core module mocks are appropriately structured for testing purposes.
82-202: Well-structured mock implementationThe V5 mock contracts correctly implement the ethers v6 pattern where methods have both direct call and
staticCallvariants. This enables comprehensive testing of both transaction execution and static validation.src/core/endorsement-chain/useEndorsementChain.ts (1)
148-162: Good refactoring to increase reusabilityThe function has been appropriately generalized by exporting it and using a more generic parameter name. This enables its use across the newly added token registry modules.
Note: The
provider as anycast on line 157 bypasses TypeScript's type checking. While this works, consider addressing the underlying type compatibility issue in a future update.package.json (1)
13-16: Well-structured e2e test orchestrationThe e2e test scripts properly coordinate starting a local Hardhat node, waiting for it to be ready, and running tests. The use of
concurrently -kensures clean process termination.src/__tests__/token-registry-functions/ownerOf.test.ts (1)
76-105: Comprehensive test coverage for success scenariosThe tests properly cover both auto-detection and explicit version specification paths, with appropriate assertions for factory calls and interface checks.
src/token-registry-functions/mint.ts (1)
23-58: Well-structured function with proper validationThe function has comprehensive documentation, validates inputs appropriately, and efficiently detects contract versions using parallel promises.
src/__tests__/token-registry-functions/returnToken.test.ts (1)
89-93: Good handling of ethers version compatibilityThe test properly mocks both
callStatic(ethers v5) andstaticCall(ethers v6) patterns, ensuring compatibility across versions.src/token-registry-functions/utils.ts (1)
27-35: Well-implemented version compatibility handlingThe function properly handles the differences between ethers v5 (returns number) and v6 (returns bigint) for chain IDs, with appropriate error handling.
src/token-registry-functions/types.ts (1)
41-51: Excellent use of discriminated union typeThe
ContractOptionstype effectively ensures that eithertitleEscrowAddressis provided, or bothtokenIdandtokenRegistryAddressare required. This provides compile-time safety for the API.src/__tests__/token-registry-functions/transfers.test.ts (2)
199-202: Good test isolation practiceProperly restores the original gas station configuration after the test, preventing interference with other tests.
2-2: Add missingbeforeAllimport-import { vi, describe, beforeAll, it, expect } from 'vitest'; +import { vi, describe, beforeAll, it, expect } from 'vitest';Note:
beforeAllis already in the import list, so this appears to be correct. Disregard this comment.Also applies to: 79-79
| // Generate test private keys (similar to Hardhat's approach) | ||
| const generateTestV5PrivateKeys = (count: number): string[] => { | ||
| const keys: string[] = []; | ||
| // Start with some well-known test keys (same as Hardhat) | ||
| const baseKeys = [ | ||
| '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', | ||
| '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d', | ||
| '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a', | ||
| '0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6', | ||
| '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a', | ||
| '0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba', | ||
| '0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e', | ||
| '0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356', | ||
| '0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97', | ||
| '0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6', | ||
| ]; | ||
|
|
||
| for (let i = 0; i < count; i++) { | ||
| if (i < baseKeys.length) { | ||
| keys.push(baseKeys[i]); | ||
| } else { | ||
| // Generate additional keys if needed | ||
| const randomKey = ethersV5.Wallet.createRandom().privateKey; | ||
| keys.push(randomKey); | ||
| } | ||
| } | ||
|
|
||
| return keys; | ||
| }; | ||
| const generateTestV6PrivateKeys = (count: number): string[] => { | ||
| const keys: string[] = []; | ||
| // Start with some well-known test keys (same as Hardhat) | ||
| const baseKeys = [ | ||
| '0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897', | ||
| '0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82', | ||
| '0xa267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1', | ||
| '0x47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd', | ||
| '0xc526ee95bf44d8fc405a158bb884d9d1238d99f0612e9f33d006bb0789009aaa', | ||
| '0x8166f546bab6da521a8369cab06c5d2b9e46670292d85c875ee9ec20e84ffb61', | ||
| '0xea6c44ac03bff858b476bba40716402b03e41b8e97e276d1baec7c37d42484a0', | ||
| '0x689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd', | ||
| '0xde9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0', | ||
| '0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e', | ||
| ]; | ||
|
|
||
| for (let i = 0; i < count; i++) { | ||
| if (i < baseKeys.length) { | ||
| keys.push(baseKeys[i]); | ||
| } else { | ||
| // Generate additional keys if needed | ||
| const randomKey = WalletV6.createRandom().privateKey; | ||
| keys.push(randomKey); | ||
| } | ||
| } | ||
|
|
||
| return keys; | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Security consideration and code duplication in test key generation
- While these are well-known test keys, consider adding a clear warning comment that these keys should never be used outside of testing.
- The two functions
generateTestV5PrivateKeysandgenerateTestV6PrivateKeyshave identical logic but different hardcoded keys. This duplication could be reduced.
+// WARNING: These are well-known test private keys. NEVER use these keys in production or with real funds!
+const TEST_KEYS_V5 = [
+ '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
+ '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',
+ // ... rest of keys
+];
+
+const TEST_KEYS_V6 = [
+ '0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897',
+ '0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82',
+ // ... rest of keys
+];
+
+const generateTestPrivateKeys = (count: number, baseKeys: string[], walletCreator: { createRandom: () => { privateKey: string } }): string[] => {
+ const keys: string[] = [];
+ for (let i = 0; i < count; i++) {
+ if (i < baseKeys.length) {
+ keys.push(baseKeys[i]);
+ } else {
+ keys.push(walletCreator.createRandom().privateKey);
+ }
+ }
+ return keys;
+};
+
-const generateTestV5PrivateKeys = (count: number): string[] => {
- const keys: string[] = [];
- // Start with some well-known test keys (same as Hardhat)
- const baseKeys = [
- '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
- // ... all keys
- ];
-
- for (let i = 0; i < count; i++) {
- if (i < baseKeys.length) {
- keys.push(baseKeys[i]);
- } else {
- // Generate additional keys if needed
- const randomKey = ethersV5.Wallet.createRandom().privateKey;
- keys.push(randomKey);
- }
- }
-
- return keys;
-};
+const generateTestV5PrivateKeys = (count: number): string[] =>
+ generateTestPrivateKeys(count, TEST_KEYS_V5, ethersV5.Wallet);
+
-const generateTestV6PrivateKeys = (count: number): string[] => {
- // ... duplicate code
-};
+const generateTestV6PrivateKeys = (count: number): string[] =>
+ generateTestPrivateKeys(count, TEST_KEYS_V6, WalletV6);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Generate test private keys (similar to Hardhat's approach) | |
| const generateTestV5PrivateKeys = (count: number): string[] => { | |
| const keys: string[] = []; | |
| // Start with some well-known test keys (same as Hardhat) | |
| const baseKeys = [ | |
| '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', | |
| '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d', | |
| '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a', | |
| '0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6', | |
| '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a', | |
| '0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba', | |
| '0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e', | |
| '0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356', | |
| '0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97', | |
| '0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6', | |
| ]; | |
| for (let i = 0; i < count; i++) { | |
| if (i < baseKeys.length) { | |
| keys.push(baseKeys[i]); | |
| } else { | |
| // Generate additional keys if needed | |
| const randomKey = ethersV5.Wallet.createRandom().privateKey; | |
| keys.push(randomKey); | |
| } | |
| } | |
| return keys; | |
| }; | |
| const generateTestV6PrivateKeys = (count: number): string[] => { | |
| const keys: string[] = []; | |
| // Start with some well-known test keys (same as Hardhat) | |
| const baseKeys = [ | |
| '0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897', | |
| '0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82', | |
| '0xa267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1', | |
| '0x47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd', | |
| '0xc526ee95bf44d8fc405a158bb884d9d1238d99f0612e9f33d006bb0789009aaa', | |
| '0x8166f546bab6da521a8369cab06c5d2b9e46670292d85c875ee9ec20e84ffb61', | |
| '0xea6c44ac03bff858b476bba40716402b03e41b8e97e276d1baec7c37d42484a0', | |
| '0x689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd', | |
| '0xde9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0', | |
| '0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e', | |
| ]; | |
| for (let i = 0; i < count; i++) { | |
| if (i < baseKeys.length) { | |
| keys.push(baseKeys[i]); | |
| } else { | |
| // Generate additional keys if needed | |
| const randomKey = WalletV6.createRandom().privateKey; | |
| keys.push(randomKey); | |
| } | |
| } | |
| return keys; | |
| }; | |
| // WARNING: These are well-known test private keys. NEVER use these keys in production or with real funds! | |
| const TEST_KEYS_V5 = [ | |
| '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', | |
| '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d', | |
| '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a', | |
| '0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6', | |
| '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a', | |
| '0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba', | |
| '0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e', | |
| '0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356', | |
| '0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97', | |
| '0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6', | |
| ]; | |
| const TEST_KEYS_V6 = [ | |
| '0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897', | |
| '0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82', | |
| '0xa267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1', | |
| '0x47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd', | |
| '0xc526ee95bf44d8fc405a158bb884d9d1238d99f0612e9f33d006bb0789009aaa', | |
| '0x8166f546bab6da521a8369cab06c5d2b9e46670292d85c875ee9ec20e84ffb61', | |
| '0xea6c44ac03bff858b476bba40716402b03e41b8e97e276d1baec7c37d42484a0', | |
| '0x689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd', | |
| '0xde9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0', | |
| '0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e', | |
| ]; | |
| const generateTestPrivateKeys = ( | |
| count: number, | |
| baseKeys: string[], | |
| walletCreator: { createRandom: () => { privateKey: string } } | |
| ): string[] => { | |
| const keys: string[] = []; | |
| for (let i = 0; i < count; i++) { | |
| if (i < baseKeys.length) { | |
| keys.push(baseKeys[i]); | |
| } else { | |
| keys.push(walletCreator.createRandom().privateKey); | |
| } | |
| } | |
| return keys; | |
| }; | |
| const generateTestV5PrivateKeys = (count: number): string[] => | |
| generateTestPrivateKeys(count, TEST_KEYS_V5, ethersV5.Wallet); | |
| const generateTestV6PrivateKeys = (count: number): string[] => | |
| generateTestPrivateKeys(count, TEST_KEYS_V6, WalletV6); |
🤖 Prompt for AI Agents
In src/__tests__/e2e/fixtures.ts between lines 45 and 101, add a clear warning
comment above both generateTestV5PrivateKeys and generateTestV6PrivateKeys
functions stating that these keys are for testing only and must never be used in
production or real environments. To reduce duplication, refactor by extracting
the common logic into a single reusable function that accepts the baseKeys array
as a parameter and returns the combined keys, then use this function in both
generateTestV5PrivateKeys and generateTestV6PrivateKeys with their respective
baseKeys.
| providers.forEach(({ ethersVersion, titleEscrowVersion }) => { | ||
| describe(`Reject Transfer Functions E2E Tests -with ethers ${ethersVersion} and token registry ${titleEscrowVersion}`, async function () { |
There was a problem hiding this comment.
Remove async from describe callback
The describe function callback should not be marked as async. This is not necessary and may cause unexpected behavior in the test runner.
-providers.forEach(({ ethersVersion, titleEscrowVersion }) => {
- describe(`Reject Transfer Functions E2E Tests -with ethers ${ethersVersion} and token registry ${titleEscrowVersion}`, async function () {
+providers.forEach(({ ethersVersion, titleEscrowVersion }) => {
+ describe(`Reject Transfer Functions E2E Tests -with ethers ${ethersVersion} and token registry ${titleEscrowVersion}`, function () {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| providers.forEach(({ ethersVersion, titleEscrowVersion }) => { | |
| describe(`Reject Transfer Functions E2E Tests -with ethers ${ethersVersion} and token registry ${titleEscrowVersion}`, async function () { | |
| providers.forEach(({ ethersVersion, titleEscrowVersion }) => { | |
| describe(`Reject Transfer Functions E2E Tests -with ethers ${ethersVersion} and token registry ${titleEscrowVersion}`, function () { |
🤖 Prompt for AI Agents
In src/__tests__/e2e/token-registry-functions/rejectTransfer.e2e.test.ts at
lines 54-55, remove the async keyword from the describe callback function. The
describe function should not be async because it does not support asynchronous
callbacks and marking it async can cause unexpected behavior in the test runner.
| before(async function () { | ||
| await network.provider.send('evm_setAutomine', [true]); // Ensure auto-mining | ||
| await network.provider.send('hardhat_reset'); // Reset network between tests | ||
| // Reset nonce tracker for clean state (especially important for v6) | ||
|
|
||
| // Get signers using our custom utility (returns ethers.Wallet[]) | ||
| // For v6, use unique private keys based on provider index to avoid nonce conflicts | ||
| const signers = ethersVersion === 'v5' ? await getSignersV5(11) : await getSignersV6(11); // Larger offset for v6 | ||
| // const signers = await hardhatEthers.getSigners(); | ||
| [deployer, owner, newOwner, holder, beneficiary, newHolder, newBeneficiary] = signers; | ||
|
|
||
| // Deploy TitleEscrowFactory first | ||
| console.log('Deploying TitleEscrowFactory...'); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
|
||
| const titleEscrowFactory = getVersionedContractFactory( | ||
| 'TitleEscrowFactory', | ||
| ethersVersion, | ||
| titleEscrowVersion, | ||
| deployer, | ||
| ); | ||
|
|
||
| TitleEscrowFactoryContract = await titleEscrowFactory.deploy(); | ||
| if (ethersVersion === 'v6') { | ||
| await TitleEscrowFactoryContract.waitForDeployment(); | ||
| } else { | ||
| await TitleEscrowFactoryContract.deployTransaction.wait(); | ||
| } | ||
|
|
||
| titleEscrowFactoryAddress = | ||
| ethersVersion === 'v5' | ||
| ? (TitleEscrowFactoryContract as ethers.Contract).address | ||
| : (TitleEscrowFactoryContract as ethersV6.Contract).target; | ||
|
|
||
| // Deploy TradeTrustToken with proper constructor arguments | ||
| console.log('Deploying TradeTrustToken...'); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
| const tradeTrustTokenFactory = getVersionedContractFactory( | ||
| 'TradeTrustToken', | ||
| ethersVersion, | ||
| titleEscrowVersion, | ||
| deployer, | ||
| ); | ||
|
|
||
| // add a time delay here | ||
|
|
||
| if (ethersVersion === 'v6') { | ||
| const nonce = await providerV6.getTransactionCount(deployer.address, 'pending'); | ||
| TradeTrustTokenContract = await tradeTrustTokenFactory.deploy( | ||
| 'Test TradeTrust Token', | ||
| 'TTT', | ||
| titleEscrowFactoryAddress, | ||
| { | ||
| nonce: nonce, | ||
| }, | ||
| ); | ||
| } else { | ||
| TradeTrustTokenContract = await tradeTrustTokenFactory.deploy( | ||
| 'Test TradeTrust Token', | ||
| 'TTT', | ||
| titleEscrowFactoryAddress, | ||
| ); | ||
| // await TradeTrustTokenContract.wait(); | ||
| } | ||
|
|
||
| tradeTrustTokenAddress = | ||
| ethersVersion === 'v5' | ||
| ? (TradeTrustTokenContract as ethers.Contract).address | ||
| : await (TradeTrustTokenContract as ethersV6.Contract).getAddress(); | ||
| console.log('TradeTrustToken deployed to:', tradeTrustTokenAddress); | ||
|
|
||
| console.log('All mock contracts deployed and initialized for E2E testing'); | ||
| console.log('Minting token...'); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
|
||
| const contractOptions: MintTokenOptions = { | ||
| tokenRegistryAddress: tradeTrustTokenAddress, | ||
| }; | ||
|
|
||
| const params: MintTokenParams = { | ||
| beneficiaryAddress: beneficiary.address, //keeping both initial holder and beneficiary same | ||
| holderAddress: holder.address, | ||
| tokenId: '0', | ||
| remarks: 'Initial mint for testing', | ||
| }; | ||
|
|
||
| const options: TransactionOptions = { | ||
| titleEscrowVersion, | ||
| chainId: CHAIN_ID.local, | ||
| id: 'test-encryption-key', | ||
| }; | ||
|
|
||
| const tx0 = await mint(contractOptions, deployer as unknown as Signer, params, options); | ||
| await tx0.wait(); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
|
||
| titleEscrow = createContract( | ||
| await TradeTrustTokenContract.ownerOf('0'), | ||
| 'TitleEscrow', | ||
| ethersVersion, | ||
| titleEscrowVersion, | ||
| deployer, | ||
| ); | ||
|
|
||
| addresses = { | ||
| tokenAddress: tradeTrustTokenAddress, | ||
| titleEscrow: titleEscrow.address || titleEscrow.target, | ||
| holder: holder.address, | ||
| beneficiary: beneficiary.address, | ||
| newHolder: newHolder.address, | ||
| newBeneficiary: newBeneficiary.address, | ||
| owner: owner.address, | ||
| newOwner: newOwner.address, | ||
| }; | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Multiple issues in test setup
- Using
awaitongetSignersV5/getSignersV6which should not be async based on the fixtures file - Magic timeout values without explanation
- Manual nonce management could lead to race conditions
- Commented-out code suggests uncertainty
- const signers = ethersVersion === 'v5' ? await getSignersV5(11) : await getSignersV6(11);
+ const signers = ethersVersion === 'v5' ? getSignersV5(11) : getSignersV6(11);
+ const DEPLOYMENT_DELAY = 1000; // ms delay between deployments to avoid nonce issues
console.log('Deploying TitleEscrowFactory...');
- await new Promise((resolve) => setTimeout(resolve, 1000));
+ await new Promise((resolve) => setTimeout(resolve, DEPLOYMENT_DELAY));
- // add a time delay here
-
if (ethersVersion === 'v6') {
+ // Get nonce just before deployment to avoid stale nonce
const nonce = await providerV6.getTransactionCount(deployer.address, 'pending');
- // await TradeTrustTokenContract.wait();
}Consider using a more robust approach for handling deployment delays and nonce management, such as a deployment helper function that handles these concerns centrally.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/__tests__/e2e/token-registry-functions/rejectTransfer.e2e.test.ts between
lines 70 and 184, fix the test setup by removing the unnecessary await on
getSignersV5/getSignersV6 calls since they are synchronous, replace magic
timeout values with explicit waits for transaction confirmations or events to
ensure deployments complete, eliminate manual nonce management by relying on the
provider or a centralized deployment helper to handle nonce and transaction
ordering, and remove commented-out code to clarify intent and reduce confusion.
| }); | ||
|
|
||
| it('should throw error if titleEscrow contract is not version v5', async () => { | ||
| const titleEscrowFactoryV4 = getVersionedContractFactory( | ||
| 'TitleEscrowFactory', | ||
| ethersVersion, | ||
| 'v4', | ||
| deployer, | ||
| ); | ||
|
|
||
| const TitleEscrowFactoryContractV4 = await titleEscrowFactoryV4.deploy(); | ||
| if (ethersVersion === 'v6') { | ||
| await TitleEscrowFactoryContractV4.waitForDeployment(); | ||
| } | ||
|
|
||
| const titleEscrowFactoryAddressV4 = | ||
| ethersVersion === 'v5' | ||
| ? (TitleEscrowFactoryContractV4 as ethers.Contract).address | ||
| : (TitleEscrowFactoryContractV4 as ethersV6.Contract).target; | ||
|
|
||
| // Deploy TradeTrustToken with proper constructor arguments | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
| const tradeTrustTokenFactoryV4 = getVersionedContractFactory( | ||
| 'TradeTrustToken', | ||
| ethersVersion, | ||
| 'v4', | ||
| deployer, | ||
| ); | ||
|
|
||
| // add a time delay here | ||
| let TradeTrustTokenContractV4: any; | ||
| if (ethersVersion === 'v6') { | ||
| const nonce = await providerV6.getTransactionCount(deployer.address, 'pending'); | ||
| TradeTrustTokenContractV4 = await tradeTrustTokenFactoryV4.deploy( | ||
| 'Test TradeTrust Token', | ||
| 'TTT', | ||
| titleEscrowFactoryAddressV4, | ||
| { | ||
| nonce: nonce, | ||
| }, | ||
| ); | ||
| } else { | ||
| TradeTrustTokenContractV4 = await tradeTrustTokenFactoryV4.deploy( | ||
| 'Test TradeTrust Token', | ||
| 'TTT', | ||
| titleEscrowFactoryAddressV4, | ||
| ); | ||
| // await TradeTrustTokenContract.wait(); | ||
| } | ||
|
|
||
| const tradeTrustTokenAddressV4 = | ||
| ethersVersion === 'v5' | ||
| ? (TradeTrustTokenContractV4 as ethers.Contract).address | ||
| : await (TradeTrustTokenContractV4 as ethersV6.Contract).getAddress(); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
|
||
| const contractOptions: MintTokenOptions = { | ||
| tokenRegistryAddress: tradeTrustTokenAddressV4, | ||
| }; | ||
|
|
||
| const params: MintTokenParams = { | ||
| beneficiaryAddress: holder.address, //keeping both initial holder and beneficiary same | ||
| holderAddress: holder.address, | ||
| tokenId: '0', | ||
| remarks: 'Initial mint for testing', | ||
| }; | ||
|
|
||
| const options: TransactionOptions = { | ||
| titleEscrowVersion: 'v4', | ||
| chainId: CHAIN_ID.local, | ||
| id: 'test-encryption-key', | ||
| }; | ||
|
|
||
| const txV4 = await mint(contractOptions, deployer as unknown as Signer, params, options); | ||
| await txV4.wait(); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
| const titleEscrowv4 = createContract( | ||
| await TradeTrustTokenContractV4.ownerOf('0'), | ||
| 'TitleEscrow', | ||
| ethersVersion, | ||
| 'v4', | ||
| deployer, | ||
| ); | ||
| const contractOptionsV4 = { | ||
| titleEscrowAddress: (titleEscrowv4.address || titleEscrowv4.target) as string, | ||
| }; | ||
|
|
||
| const paramsV4 = { | ||
| newBeneficiaryAddress: addresses.newBeneficiary, | ||
| newHolderAddress: addresses.newHolder, | ||
| remarks: 'Transfer both roles', | ||
| }; | ||
|
|
||
| const optionsV4 = { | ||
| chainId: CHAIN_ID.local, | ||
| titleEscrowVersion: 'v4' as const, | ||
| id: 'test-encryption-id', | ||
| }; | ||
|
|
||
| // Execute transfer using current holder (newHolder) | ||
| const tx = await transferOwners(contractOptionsV4, holder as any, paramsV4, optionsV4); | ||
| await tx.wait(); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
| const contractOptionsV4Reject = { | ||
| titleEscrowAddress: titleEscrowv4.address || titleEscrowv4.target, | ||
| }; | ||
|
|
||
| const paramsV4Reject = { | ||
| remarks: 'Reject transfer holder to new address', | ||
| }; | ||
|
|
||
| const optionsV4Reject = { | ||
| chainId: CHAIN_ID.local, | ||
| titleEscrowVersion: 'v4' as const, | ||
| id: 'test-encryption-id', | ||
| }; | ||
|
|
||
| // Execute transfer using type assertion to bypass type issues | ||
| try { | ||
| await rejectTransferHolder( | ||
| contractOptionsV4Reject, | ||
| newHolder, | ||
| paramsV4Reject, | ||
| optionsV4Reject, | ||
| ); | ||
| } catch (error: any) { | ||
| expect(error.message).to.equal('Only Token Registry V5 is supported'); | ||
| } | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Extract duplicate v4 contract deployment logic
This test and similar ones in the file contain duplicate code for deploying v4 contracts. Consider extracting this into a helper function to improve maintainability.
// Add this helper function at the module level
async function deployV4Contracts(ethersVersion: string, deployer: any) {
const titleEscrowFactoryV4 = getVersionedContractFactory(
'TitleEscrowFactory',
ethersVersion,
'v4',
deployer,
);
const TitleEscrowFactoryContractV4 = await titleEscrowFactoryV4.deploy();
if (ethersVersion === 'v6') {
await TitleEscrowFactoryContractV4.waitForDeployment();
}
const titleEscrowFactoryAddressV4 =
ethersVersion === 'v5'
? (TitleEscrowFactoryContractV4 as ethers.Contract).address
: (TitleEscrowFactoryContractV4 as ethersV6.Contract).target;
// ... rest of the deployment logic
return { titleEscrowv4, tradeTrustTokenAddressV4 };
}
// Then use it in tests:
const { titleEscrowv4 } = await deployV4Contracts(ethersVersion, deployer);🤖 Prompt for AI Agents
In src/__tests__/e2e/token-registry-functions/rejectTransfer.e2e.test.ts from
lines 396 to 524, the test contains duplicated code for deploying v4 contracts
including TitleEscrowFactory and TradeTrustToken. To fix this, extract the
repeated deployment logic into a reusable helper function at the module level
that accepts ethersVersion and deployer as parameters, performs the deployment
steps, and returns the deployed contract instances or addresses. Then replace
the duplicated code in the test with calls to this helper function to improve
maintainability and reduce redundancy.
| } | ||
| }); | ||
|
|
||
| it('should throw error when callStatic rejectTransferHolder fails', async () => { |
There was a problem hiding this comment.
Inconsistent test descriptions
The test description mentions "rejectTransferHolder" but the actual test is for "rejectTransferBeneficiary" and "rejectTransferOwners" respectively.
- it('should throw error when callStatic rejectTransferHolder fails', async () => {
+ it('should throw error when callStatic rejectTransferBeneficiary fails', async () => {
- it('should throw error when callStatic rejectTransferHolder fails', async () => {
+ it('should throw error when callStatic rejectTransferOwners fails', async () => {Also applies to: 1459-1459
🤖 Prompt for AI Agents
In src/__tests__/e2e/token-registry-functions/rejectTransfer.e2e.test.ts at
lines 984 and 1459, the test descriptions incorrectly mention
"rejectTransferHolder" while the tests are actually for
"rejectTransferBeneficiary" and "rejectTransferOwners". Update the test
descriptions to accurately reflect the function being tested by replacing
"rejectTransferHolder" with the correct function names
"rejectTransferBeneficiary" and "rejectTransferOwners" respectively.
| ); | ||
| } | ||
|
|
||
| if (!titleEscrowAddress) throw new Error('Token registry address is required'); |
There was a problem hiding this comment.
Fix incorrect error messages
The error messages incorrectly state "Token registry address is required" when they should say "Title escrow address is required".
- if (!titleEscrowAddress) throw new Error('Token registry address is required');
+ if (!titleEscrowAddress) throw new Error('Title escrow address is required');Also applies to: 211-211
🤖 Prompt for AI Agents
In src/token-registry-functions/rejectTransfers.ts at lines 128 and 211, the
error messages incorrectly state "Token registry address is required" when they
should say "Title escrow address is required". Update the error messages in both
lines to correctly reflect that the title escrow address is required.
| // Check callStatic (dry run) | ||
| try { | ||
| const isV6 = isV6EthersProvider(signer.provider); | ||
| const args = isV5TT ? [encryptedRemarks] : []; | ||
|
|
||
| if (isV6) { | ||
| await (tradeTrustTokenContract as ContractV6).burn.staticCall(...args); | ||
| } else { | ||
| await (tradeTrustTokenContract as ContractV5).callStatic.burn(...args); | ||
| } | ||
| } catch (e) { | ||
| console.error('callStatic failed:', e); | ||
| throw new Error('Pre-check (callStatic) for acceptReturned failed'); | ||
| } | ||
|
|
||
| const txOptions = await getTxOptions(signer, chainId, maxFeePerGas, maxPriorityFeePerGas); | ||
|
|
||
| // Send the actual transaction | ||
|
|
||
| if (isV5TT) { | ||
| return await tradeTrustTokenContract.burn(tokenId, encryptedRemarks, txOptions); | ||
| } else if (isV4TT) { | ||
| return await tradeTrustTokenContract.burn(tokenId, txOptions); | ||
| } |
There was a problem hiding this comment.
Fix incorrect burn function arguments
The burn function is being called with incorrect arguments. The tokenId parameter is missing in the staticCall but included in the actual transaction with wrong positioning.
// Check callStatic (dry run)
try {
const isV6 = isV6EthersProvider(signer.provider);
- const args = isV5TT ? [encryptedRemarks] : [];
+ const args = isV5TT ? [tokenId, encryptedRemarks] : [tokenId];
if (isV6) {
await (tradeTrustTokenContract as ContractV6).burn.staticCall(...args);
} else {
await (tradeTrustTokenContract as ContractV5).callStatic.burn(...args);
}
} catch (e) {
console.error('callStatic failed:', e);
throw new Error('Pre-check (callStatic) for acceptReturned failed');
}
const txOptions = await getTxOptions(signer, chainId, maxFeePerGas, maxPriorityFeePerGas);
// Send the actual transaction
if (isV5TT) {
return await tradeTrustTokenContract.burn(tokenId, encryptedRemarks, txOptions);
} else if (isV4TT) {
return await tradeTrustTokenContract.burn(tokenId, txOptions);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Check callStatic (dry run) | |
| try { | |
| const isV6 = isV6EthersProvider(signer.provider); | |
| const args = isV5TT ? [encryptedRemarks] : []; | |
| if (isV6) { | |
| await (tradeTrustTokenContract as ContractV6).burn.staticCall(...args); | |
| } else { | |
| await (tradeTrustTokenContract as ContractV5).callStatic.burn(...args); | |
| } | |
| } catch (e) { | |
| console.error('callStatic failed:', e); | |
| throw new Error('Pre-check (callStatic) for acceptReturned failed'); | |
| } | |
| const txOptions = await getTxOptions(signer, chainId, maxFeePerGas, maxPriorityFeePerGas); | |
| // Send the actual transaction | |
| if (isV5TT) { | |
| return await tradeTrustTokenContract.burn(tokenId, encryptedRemarks, txOptions); | |
| } else if (isV4TT) { | |
| return await tradeTrustTokenContract.burn(tokenId, txOptions); | |
| } | |
| // Check callStatic (dry run) | |
| try { | |
| const isV6 = isV6EthersProvider(signer.provider); | |
| const args = isV5TT ? [tokenId, encryptedRemarks] : [tokenId]; | |
| if (isV6) { | |
| await (tradeTrustTokenContract as ContractV6).burn.staticCall(...args); | |
| } else { | |
| await (tradeTrustTokenContract as ContractV5).callStatic.burn(...args); | |
| } | |
| } catch (e) { | |
| console.error('callStatic failed:', e); | |
| throw new Error('Pre-check (callStatic) for acceptReturned failed'); | |
| } | |
| const txOptions = await getTxOptions(signer, chainId, maxFeePerGas, maxPriorityFeePerGas); | |
| // Send the actual transaction | |
| if (isV5TT) { | |
| return await tradeTrustTokenContract.burn(tokenId, encryptedRemarks, txOptions); | |
| } else if (isV4TT) { | |
| return await tradeTrustTokenContract.burn(tokenId, txOptions); | |
| } |
🤖 Prompt for AI Agents
In src/token-registry-functions/returnToken.ts around lines 291 to 314, the burn
function calls have inconsistent and incorrect arguments: the staticCall is
missing the tokenId parameter, and the actual transaction call has tokenId and
encryptedRemarks in the wrong order. Fix this by ensuring both staticCall and
actual burn calls include tokenId as the first argument, followed by
encryptedRemarks if required, matching the function signature and keeping
argument order consistent.
| ); | ||
| } | ||
|
|
||
| if (!titleEscrowAddress) throw new Error('Token registry address is required'); |
There was a problem hiding this comment.
Fix incorrect error messages for title escrow address checks
Multiple instances where the error message incorrectly states "Token registry address is required" when checking for title escrow address.
- if (!titleEscrowAddress) throw new Error('Token registry address is required');
+ if (!titleEscrowAddress) throw new Error('Title escrow address is required');Also applies to: 186-186, 311-311, 450-450
🤖 Prompt for AI Agents
In src/token-registry-functions/transfer.ts at lines 63, 186, 311, and 450, the
error messages incorrectly state "Token registry address is required" when they
should refer to the title escrow address. Update the error messages in these
lines to correctly say "Title escrow address is required" to accurately reflect
the validation being performed.
| // check for current holder and signer | ||
| // const currentHolder = await titleEscrowContract.holder(); | ||
|
|
||
| // if (currentHolder.toLowerCase() === holderAddress.toLowerCase()) { | ||
| // throw new Error('Cannot transfer to current holder'); | ||
| // } | ||
| // const signerAddress = await getSignerAddressSafe(signer); | ||
| // if (currentHolder.toLowerCase() !== signerAddress.toLowerCase()) { | ||
| // throw new Error('Only the current holder can transfer'); | ||
| // } | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Remove or implement commented validation logic
Multiple blocks of validation code are commented out. These checks appear to verify:
- Current holder/beneficiary vs new addresses
- Signer authorization
Either implement these validations properly or remove the commented code. Leaving them suggests incomplete implementation.
Would you like me to help implement proper validation logic for these transfer functions?
Also applies to: 231-240, 355-371, 491-500
🤖 Prompt for AI Agents
In src/token-registry-functions/transfer.ts around lines 110 to 120, the
commented-out validation code that checks if the current holder matches the new
holder and verifies the signer authorization should be either fully implemented
or removed to avoid incomplete logic. To fix this, uncomment the code and ensure
it correctly fetches the current holder from the contract, compares it
case-insensitively with the holderAddress and signerAddress, and throws
appropriate errors if validations fail. Apply the same approach to the similar
commented code blocks at lines 231-240, 355-371, and 491-500.
| if (!maxFeePerGas || !maxPriorityFeePerGas) { | ||
| chainId = chainId ?? ((await getChainIdSafe(signer)) as unknown as CHAIN_ID); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid parameter reassignment and unsafe type assertion
Reassigning parameters and using as unknown as type assertions can lead to issues.
// If gas values are missing, query gas station if available
if (!maxFeePerGas || !maxPriorityFeePerGas) {
- chainId = chainId ?? ((await getChainIdSafe(signer)) as unknown as CHAIN_ID);
+ const effectiveChainId = chainId ?? (await getChainIdSafe(signer));
+ if (!Object.values(CHAIN_ID).includes(effectiveChainId as any)) {
+ throw new Error(`Unsupported chain ID: ${effectiveChainId}`);
+ }
+ const typedChainId = effectiveChainId as CHAIN_ID;
- const gasStation = SUPPORTED_CHAINS[chainId]?.gasStation;
+ const gasStation = SUPPORTED_CHAINS[typedChainId]?.gasStation;🤖 Prompt for AI Agents
In src/token-registry-functions/utils.ts around lines 14 to 15, avoid
reassigning the parameter chainId and using the unsafe type assertion 'as
unknown as CHAIN_ID'. Instead, declare a new local variable to hold the chainId
value and use a safer type assertion or proper type guard when assigning the
result of getChainIdSafe(signer). This prevents side effects from parameter
mutation and improves type safety.
## [1.8.0](v1.7.4...v1.8.0) (2025-07-30) ### Features * token registry functions ([#96](#96)) ([6c379e9](6c379e9))
|
🎉 This PR is included in version 1.8.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
* fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] ## [1.5.4](v1.5.3...v1.5.4) (2025-06-17) ### Bug Fixes * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] ## [1.5.5](v1.5.4...v1.5.5) (2025-06-18) ### Bug Fixes * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * feat: support passing titleEscrowAddress to fetchEndorsementChain (#80) Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> * chore(release): 1.6.0 [skip ci] ## [1.6.0](v1.5.5...v1.6.0) (2025-07-14) ### Features * support passing titleEscrowAddress to fetchEndorsementChain ([#80](#80)) ([aa7b4f0](aa7b4f0)) * feat: add astron v5 (#81) Co-authored-by: maxufeng <maxufeng@caict.ac.cn> * chore(release): 1.7.0 [skip ci] ## [1.7.0](v1.6.0...v1.7.0) (2025-07-15) ### Features * add astron v5 ([#81](#81)) ([0bebeae](0bebeae)) * fix: update tradetrust-tt/tradetrust package (#87) * fix: update tradetrust-tt/tradetrust package * fix: update version * fix: update imports * chore(release): 1.7.1 [skip ci] ## [1.7.1](v1.7.0...v1.7.1) (2025-07-25) ### Bug Fixes * update tradetrust-tt/tradetrust package ([#87](#87)) ([e4f75a4](e4f75a4)) * fix: upgrade packages (#88) * chore(release): 1.7.2 [skip ci] ## [1.7.2](v1.7.1...v1.7.2) (2025-07-28) ### Bug Fixes * upgrade packages ([#88](#88)) ([0cc314e](0cc314e)) * fix: error message types (#89) * chore(release): 1.7.3 [skip ci] ## [1.7.3](v1.7.2...v1.7.3) (2025-07-28) ### Bug Fixes * error message types ([#89](#89)) ([d83bada](d83bada)) * fix: upgrade packages (#90) * chore(release): 1.7.4 [skip ci] ## [1.7.4](v1.7.3...v1.7.4) (2025-07-29) ### Bug Fixes * upgrade packages ([#90](#90)) ([758651d](758651d)) * feat: token registry functions (#96) * chore(release): 1.8.0 [skip ci] ## [1.8.0](v1.7.4...v1.8.0) (2025-07-30) ### Features * token registry functions ([#96](#96)) ([6c379e9](6c379e9)) * fix: accept return function (#97) * chore(release): 1.8.1 [skip ci] ## [1.8.1](v1.8.0...v1.8.1) (2025-08-07) ### Bug Fixes * accept return function ([#97](#97)) ([6398017](6398017)) * fix: update edsa w3c verifier * fix: update vefiable doc v2.0 * feat: token registry functions (#74) * chore(release): 1.6.0-alpha.1 [skip ci] ## [1.6.0-alpha.1](v1.5.3...v1.6.0-alpha.1) (2025-06-30) ### Features * token registry functions ([#74](#74)) ([5690fcd](5690fcd)) ### Miscellaneous Chores * back merge ([#75](#75)) ([7cc1891](7cc1891)), closes [#72](#72) [#72](#72) [#73](#73) [#73](#73) * feat: mint function (#78) * fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] ## [1.5.4](v1.5.3...v1.5.4) (2025-06-17) ### Bug Fixes * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] ## [1.5.5](v1.5.4...v1.5.5) (2025-06-18) ### Bug Fixes * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * feat: add transfer holder function * feat: add transfer owners beneficiary * chore: tests cleanup * chore: tests cleanup * fix: remove console * fix: rever useendorement chain * fix: remove console * feat: add reject transfer functions * chore: trigger rebuild after rebase * chore(release): 1.5.4 [skip ci] * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * feat: add transfer holder function * feat: add transfer owners beneficiary * chore: tests cleanup * fix: remove console * fix: rever useendorement chain * feat: add reject transfer functions * chore: trigger rebuild after rebase * chore: trigger rebuild after rebase * feat: token registry return functions * feat: add mint function * fix: update fixes * fix: update tests * revert: revert changes --------- Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Ng Han Inn <43451336+nghaninn@users.noreply.github.com> * feat: owner of function (#79) * feat: add ownerOf function * feat: add test cases * fix: update test cases for ownerof function * fix: update imports * fix: update imports * chore(release): 1.6.0-alpha.2 [skip ci] ## [1.6.0-alpha.2](v1.6.0-alpha.1...v1.6.0-alpha.2) (2025-07-15) ### Features * mint function ([#78](#78)) ([2ea52ce](2ea52ce)), closes [#72](#72) [#72](#72) [#73](#73) [#73](#73) [#72](#72) * owner of function ([#79](#79)) ([81d0e36](81d0e36)) * chore: e2e transfers tests (#82) * feat: add ownerOf function * feat: add test cases * fix: update test cases for ownerof function * chore: add e2e test for transfer functions * chore: add e2e test for transfer functions * feat: add ownerOf function * feat: add test cases * fix: update test cases for ownerof function * chore: add e2e test for transfer functions * chore: add e2e test for transfer functions * fix: update mock tests * fix: update mock test fixtures * fix: update mock tests for mint and return * fix: update test script * fix: update imports * fix: update gitignore * fix: delete cache * fix: update imports * chore: e2e tests reject transfer (#83) * chore: e2e tests for reject functions * fix: reject function ethers v6 compatible * fix: update imports * fix: mock test cases * fix: import fixed * fix: e2e return token tests (#84) * chore: e2e tests for reject functions * fix: reject function ethers v6 compatible * fix: update imports * fix: mock test cases * fix: static call fixes * chore: add e2e test cases * fix: update imports * fix: update imports * fix: tests * fix: mock functions * fix: change name * fix: update imports * fix: update src imports * chore(release): 1.6.0-alpha.3 [skip ci] ## [1.6.0-alpha.3](v1.6.0-alpha.2...v1.6.0-alpha.3) (2025-07-18) ### Bug Fixes * e2e return token tests ([#84](#84)) ([703be01](703be01)) ### Miscellaneous Chores * e2e tests reject transfer ([#83](#83)) ([58a8da2](58a8da2)) * e2e transfers tests ([#82](#82)) ([145e763](145e763)) * chore: merge main into v1 (#85) * fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] ## [1.5.4](v1.5.3...v1.5.4) (2025-06-17) ### Bug Fixes * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] ## [1.5.5](v1.5.4...v1.5.5) (2025-06-18) ### Bug Fixes * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * feat: support passing titleEscrowAddress to fetchEndorsementChain (#80) Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> * chore(release): 1.6.0 [skip ci] ## [1.6.0](v1.5.5...v1.6.0) (2025-07-14) ### Features * support passing titleEscrowAddress to fetchEndorsementChain ([#80](#80)) ([aa7b4f0](aa7b4f0)) * feat: add astron v5 (#81) Co-authored-by: maxufeng <maxufeng@caict.ac.cn> * chore(release): 1.7.0 [skip ci] ## [1.7.0](v1.6.0...v1.7.0) (2025-07-15) ### Features * add astron v5 ([#81](#81)) ([0bebeae](0bebeae)) --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Ng Han Inn <43451336+nghaninn@users.noreply.github.com> Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> Co-authored-by: caict-develop-zhangbo <68949988+caict-develop-zhangbo@users.noreply.github.com> Co-authored-by: maxufeng <maxufeng@caict.ac.cn> * fix: trigger release (#86) Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> * chore(release): 1.6.0-alpha.4 [skip ci] ## [1.6.0-alpha.4](v1.6.0-alpha.3...v1.6.0-alpha.4) (2025-07-23) ### Bug Fixes * trigger release ([#86](#86)) ([d2fb6fb](d2fb6fb)) ### Miscellaneous Chores * merge main into v1 ([#85](#85)) ([b81b422](b81b422)), closes [#72](#72) [#72](#72) [#73](#73) [#73](#73) [#80](#80) [#80](#80) [#81](#81) [#81](#81) * chore: rebase v1 with main (#95) * fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * feat: support passing titleEscrowAddress to fetchEndorsementChain (#80) Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> * chore(release): 1.6.0 [skip ci] * support passing titleEscrowAddress to fetchEndorsementChain ([#80](#80)) ([aa7b4f0](aa7b4f0)) * feat: add astron v5 (#81) Co-authored-by: maxufeng <maxufeng@caict.ac.cn> * chore(release): 1.7.0 [skip ci] * add astron v5 ([#81](#81)) ([0bebeae](0bebeae)) * fix: update tradetrust-tt/tradetrust package (#87) * fix: update tradetrust-tt/tradetrust package * fix: update version * fix: update imports * chore(release): 1.7.1 [skip ci] * update tradetrust-tt/tradetrust package ([#87](#87)) ([e4f75a4](e4f75a4)) * fix: upgrade packages (#88) * chore(release): 1.7.2 [skip ci] * upgrade packages ([#88](#88)) ([0cc314e](0cc314e)) * fix: error message types (#89) * chore(release): 1.7.3 [skip ci] * error message types ([#89](#89)) ([d83bada](d83bada)) * fix: upgrade packages (#90) * chore(release): 1.7.4 [skip ci] * upgrade packages ([#90](#90)) ([758651d](758651d)) --------- Co-authored-by: RishabhS7 <59636880+RishabhS7@users.noreply.github.com> Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Ng Han Inn <43451336+nghaninn@users.noreply.github.com> Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> Co-authored-by: caict-develop-zhangbo <68949988+caict-develop-zhangbo@users.noreply.github.com> Co-authored-by: maxufeng <maxufeng@caict.ac.cn> * fix: add w3c credential status check (#72) * fix: add w3c credential status check * fix: update test * fix: update enum status codes * fix: remove console * chore(release): 1.5.4 [skip ci] * add w3c credential status check ([#72](#72)) ([0111cb3](0111cb3)) * fix: upgrade package (#73) * chore(release): 1.5.5 [skip ci] * upgrade package ([#73](#73)) ([3c6c9c7](3c6c9c7)) * fix: update edsa w3c verifier * fix: resolve conflicts * fix: rebase * fix: resolve conflicts * fix: update package lock * fix: resolve conflicts * fix: verify test * fix: cryptosuit types --------- Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net> Co-authored-by: Ng Han Inn <43451336+nghaninn@users.noreply.github.com> Co-authored-by: Moiz Shaikh <58319530+Moiz47@users.noreply.github.com> Co-authored-by: moiz-sgtradex <moiz.shaikh@sgtradextech.com> Co-authored-by: caict-develop-zhangbo <68949988+caict-develop-zhangbo@users.noreply.github.com> Co-authored-by: maxufeng <maxufeng@caict.ac.cn> Co-authored-by: rongquan1 <rongquan.low@gmail.com>
## [1.6.0-alpha.5](v1.6.0-alpha.4...v1.6.0-alpha.5) (2025-08-19) ### Bug Fixes * add w3c version detection function ([#103](#103)) ([3270cc6](3270cc6)) ### Miscellaneous Chores * ecdsa w3c verify ([#100](#100)) ([484e1ff](484e1ff)), closes [#72](#72) [#72](#72) [#73](#73) [#73](#73) [#80](#80) [#80](#80) [#81](#81) [#81](#81) [#87](#87) [#87](#87) [#88](#88) [#88](#88) [#89](#89) [#89](#89) [#90](#90) [#90](#90) [#96](#96) [#96](#96) [#97](#97) [#97](#97) [#74](#74) [#74](#74) [#72](#72) [#72](#72) [#73](#73) [#73](#73) [#78](#78) [#72](#72) [#72](#72) [#73](#73) [#73](#73) [#72](#72) * rebase v1 with main ([#95](#95)) ([b54b146](b54b146)), closes [#72](#72) [#72](#72) [#73](#73) [#73](#73) [#80](#80) [#80](#80) [#81](#81) [#81](#81) [#87](#87) [#87](#87) [#88](#88) [#88](#88) [#89](#89) [#89](#89) [#90](#90) [#90](#90)
|
🎉 This PR is included in version 1.6.0-alpha.5 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
Adding v1 alpha branch changes to main
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Chores