Dargon789/sequence.js
在 GitHub 查看# Sequence diagram for ChainSessionManager cached signed call reuse on relay
Open
#266 创建于 2026年2月3日
dependenciesdocumentationduplicateenhancementgood first issuejavascript
仓库指标
- Star
- (1 star)
- PR 合并指标
- (PR 指标待抓取)
描述
Reviewer's Guide
Adds new userdata service RPC methods and types, introduces caching of recently signed calls in the dapp ChainSessionManager to avoid redundant signing, and bumps multiple packages to 3.0.0-beta.12 with corresponding changelog and changeset updates for a beta release with dapp connector fixes.
Sequence diagram for ChainSessionManager cached signed call reuse on relay
sequenceDiagram
actor Dapp
participant ChainSessionManager
participant Relayer
Dapp->>ChainSessionManager: sendTransaction(transactions)
ChainSessionManager->>ChainSessionManager: build callsToSend from transactions
ChainSessionManager->>ChainSessionManager: cached = _getCachedSignedCall(callsToSend)
alt cache hit and not expired
ChainSessionManager-->>ChainSessionManager: use cached.signedCall
else cache miss or expired or fingerprint mismatch
ChainSessionManager->>ChainSessionManager: signedCalls = _buildAndSignCalls(callsToSend)
ChainSessionManager->>ChainSessionManager: fingerprint = _fingerprintCalls(callsToSend)
ChainSessionManager->>ChainSessionManager: lastSignedCallCache = { fingerprint, signedCall, createdAtMs }
end
ChainSessionManager->>Relayer: relay(signedCalls.to, signedCalls.data, chainId)
Relayer-->>ChainSessionManager: hash
ChainSessionManager->>Relayer: waitForTransactionReceipt(hash.opHash, chainId)
Relayer-->>ChainSessionManager: status
ChainSessionManager-->>Dapp: transaction result based on status
ER diagram for wallet userdata entities introduced in userdata service
erDiagram
Wallet {
string address PK
number ecosystem
string updatedAt
string createdAt
}
WalletPreferences {
string walletAddress FK
boolean manualSigning
boolean hideUnlistedTokens
boolean includeTestnets
string currency
}
WalletSigner {
string walletAddress FK
string signerAddress
string kind
string email
string updatedAt
string createdAt
}
Session {
string walletAddress FK
string sessionAddress
string appUrl
string updatedAt
string createdAt
}
Contact {
string walletAddress FK
string contactAddress
string nickname
string updatedAt
string createdAt
}
WatchedWallet {
string walletAddress FK
string watchedAddress
string nickname
string updatedAt
string createdAt
}
DiscoverFavorite {
string walletAddress FK
int id
string dappId
string createdAt
}
DiscoverHistory {
string walletAddress FK
int id
string dappId
string accessedAt
}
TokenFavorite {
string walletAddress FK
int id
string chainId
string contractAddress
string tokenId
string createdAt
}
Wallet ||--|| WalletPreferences : has
Wallet ||--o{ WalletSigner : has
Wallet ||--o{ Session : has
Wallet ||--o{ Contact : has
Wallet ||--o{ WatchedWallet : has
Wallet ||--o{ DiscoverFavorite : has
Wallet ||--o{ DiscoverHistory : has
Wallet ||--o{ TokenFavorite : has
Class diagram for new userdata service RPC types and client
classDiagram
class UserDataClient {
<<interface>>
+getCapabilities(headers, signal) GetCapabilitiesResponse
+getAccessToken(req, headers, signal) GetAccessTokenResponse
+getIdentityToken(req, headers, signal) GetIdentityTokenResponse
+getWalletPreferences(req, headers, signal) GetWalletPreferencesResponse
+putWalletPreferences(req, headers, signal) PutWalletPreferencesResponse
+listWalletSigners(req, headers, signal) ListWalletSignersResponse
+putWalletSigner(req, headers, signal) PutWalletSignerResponse
+deleteWalletSigner(req, headers, signal) DeleteWalletSignerResponse
+listSessions(req, headers, signal) ListSessionsResponse
+putSession(req, headers, signal) PutSessionResponse
+deleteSession(req, headers, signal) DeleteSessionResponse
+listContacts(req, headers, signal) ListContactsResponse
+putContact(req, headers, signal) PutContactResponse
+deleteContact(req, headers, signal) DeleteContactResponse
+listWatchedWallets(req, headers, signal) ListWatchedWalletsResponse
+putWatchedWallet(req, headers, signal) PutWatchedWalletResponse
+deleteWatchedWallet(req, headers, signal) DeleteWatchedWalletResponse
+listDiscoverFavorites(req, headers, signal) ListDiscoverFavoritesResponse
+putDiscoverFavorite(req, headers, signal) PutDiscoverFavoriteResponse
+deleteDiscoverFavorite(req, headers, signal) DeleteDiscoverFavoriteResponse
+listDiscoverHistory(req, headers, signal) ListDiscoverHistoryResponse
+putDiscoverHistory(req, headers, signal) PutDiscoverHistoryResponse
+deleteDiscoverHistory(req, headers, signal) DeleteDiscoverHistoryResponse
+listTokenFavorites(req, headers, signal) ListTokenFavoritesResponse
+putTokenFavorite(req, headers, signal) PutTokenFavoriteResponse
+deleteTokenFavorite(req, headers, signal) DeleteTokenFavoriteResponse
}
class UserData {
-fetch
-url
+getCapabilities(headers, signal) GetCapabilitiesResponse
+getAccessToken(req, headers, signal) GetAccessTokenResponse
+getIdentityToken(req, headers, signal) GetIdentityTokenResponse
+getWalletPreferences(req, headers, signal) GetWalletPreferencesResponse
+putWalletPreferences(req, headers, signal) PutWalletPreferencesResponse
+listWalletSigners(req, headers, signal) ListWalletSignersResponse
+putWalletSigner(req, headers, signal) PutWalletSignerResponse
+deleteWalletSigner(req, headers, signal) DeleteWalletSignerResponse
+listSessions(req, headers, signal) ListSessionsResponse
+putSession(req, headers, signal) PutSessionResponse
+deleteSession(req, headers, signal) DeleteSessionResponse
+listContacts(req, headers, signal) ListContactsResponse
+putContact(req, headers, signal) PutContactResponse
+deleteContact(req, headers, signal) DeleteContactResponse
+listWatchedWallets(req, headers, signal) ListWatchedWalletsResponse
+putWatchedWallet(req, headers, signal) PutWatchedWalletResponse
+deleteWatchedWallet(req, headers, signal) DeleteWatchedWalletResponse
+listDiscoverFavorites(req, headers, signal) ListDiscoverFavoritesResponse
+putDiscoverFavorite(req, headers, signal) PutDiscoverFavoriteResponse
+deleteDiscoverFavorite(req, headers, signal) DeleteDiscoverFavoriteResponse
+listDiscoverHistory(req, headers, signal) ListDiscoverHistoryResponse
+putDiscoverHistory(req, headers, signal) PutDiscoverHistoryResponse
+deleteDiscoverHistory(req, headers, signal) DeleteDiscoverHistoryResponse
+listTokenFavorites(req, headers, signal) ListTokenFavoritesResponse
+putTokenFavorite(req, headers, signal) PutTokenFavoriteResponse
+deleteTokenFavorite(req, headers, signal) DeleteTokenFavoriteResponse
}
UserDataClient <|.. UserData
class Wallet {
+string address
+number ecosystem
+WalletPreferences preferences
+string updatedAt
+string createdAt
}
class WalletPreferences {
+boolean manualSigning
+boolean hideUnlistedTokens
+boolean includeTestnets
+string currency
}
class WalletSigner {
+string walletAddress
+string signerAddress
+string kind
+string email
+string updatedAt
+string createdAt
}
class WalletSignerProps {
+string address
+string kind
+string email
}
class Session {
+string walletAddress
+string sessionAddress
+string appUrl
+string updatedAt
+string createdAt
}
class SessionProps {
+string address
+string appUrl
}
class Contact {
+string walletAddress
+string contactAddress
+string nickname
+string updatedAt
+string createdAt
}
class ContactProps {
+string address
+string nickname
}
class WatchedWallet {
+string walletAddress
+string watchedAddress
+string nickname
+string updatedAt
+string createdAt
}
class WatchedWalletProps {
+string watchedAddress
+string nickname
}
class DiscoverFavorite {
+string walletAddress
+number id
+string dappId
+string createdAt
}
class DiscoverHistory {
+string walletAddress
+number id
+string dappId
+string accessedAt
}
class DiscoverProps {
+string dappId
}
class TokenFavorite {
+string walletAddress
+number id
+string chainId
+string contractAddress
+string tokenId
+string createdAt
}
class TokenFavoriteProps {
+string chainId
+string contractAddress
+string tokenId
}
class GetWalletPreferencesRequest {
+string wallet
}
class GetWalletPreferencesResponse {
+WalletPreferences preferences
}
class PutWalletPreferencesRequest {
+string wallet
+WalletPreferences preferences
}
class PutWalletPreferencesResponse {
}
class ListWalletSignersRequest {
+string wallet
+number pageSize
+string cursor
}
class ListWalletSignersResponse {
+WalletSigner[] signers
+string nextCursor
}
class PutWalletSignerRequest {
+string wallet
+WalletSignerProps signer
}
class PutWalletSignerResponse {
+WalletSigner signer
}
class DeleteWalletSignerRequest {
+string wallet
+string signer
}
class DeleteWalletSignerResponse {
}
class ListSessionsRequest {
+string wallet
+number pageSize
+string cursor
}
class ListSessionsResponse {
+Session[] sessions
+string nextCursor
}
class PutSessionRequest {
+string wallet
+SessionProps session
}
class PutSessionResponse {
+Session session
}
class DeleteSessionRequest {
+string wallet
+string session
}
class DeleteSessionResponse {
}
class ListContactsRequest {
+string wallet
+number pageSize
+string cursor
}
class ListContactsResponse {
+Contact[] contacts
+string nextCursor
}
class PutContactRequest {
+string wallet
+ContactProps contact
}
class PutContactResponse {
+Contact contact
}
class DeleteContactRequest {
+string wallet
+string contact
}
class DeleteContactResponse {
}
class ListWatchedWalletsRequest {
+string wallet
+number pageSize
+string cursor
}
class ListWatchedWalletsResponse {
+WatchedWallet[] watchedWallets
+string nextCursor
}
class PutWatchedWalletRequest {
+string wallet
+WatchedWalletProps watchedWallet
}
class PutWatchedWalletResponse {
+WatchedWallet watchedWallet
}
class DeleteWatchedWalletRequest {
+string wallet
+string watchedWallet
}
class DeleteWatchedWalletResponse {
}
class ListDiscoverFavoritesRequest {
+string wallet
+number pageSize
+string cursor
}
class ListDiscoverFavoritesResponse {
+DiscoverFavorite[] favorites
+string nextCursor
}
class PutDiscoverFavoriteRequest {
+string wallet
+DiscoverProps favorite
}
class PutDiscoverFavoriteResponse {
+DiscoverFavorite favorite
}
class DeleteDiscoverFavoriteRequest {
+string wallet
+number id
}
class DeleteDiscoverFavoriteResponse {
}
class ListDiscoverHistoryRequest {
+string wallet
+number pageSize
+string cursor
}
class ListDiscoverHistoryResponse {
+DiscoverHistory[] history
+string nextCursor
}
class PutDiscoverHistoryRequest {
+string wallet
+DiscoverProps history
}
class PutDiscoverHistoryResponse {
+DiscoverHistory history
}
class DeleteDiscoverHistoryRequest {
+string wallet
+number id
}
class DeleteDiscoverHistoryResponse {
}
class ListTokenFavoritesRequest {
+string wallet
+number pageSize
+string cursor
}
class ListTokenFavoritesResponse {
+TokenFavorite[] favorites
+string nextCursor
}
class PutTokenFavoriteRequest {
+string wallet
+TokenFavoriteProps favorite
}
class PutTokenFavoriteResponse {
+TokenFavorite favorite
}
class DeleteTokenFavoriteRequest {
+string wallet
+number id
}
class DeleteTokenFavoriteResponse {
}
UserData --> GetWalletPreferencesRequest
UserData --> GetWalletPreferencesResponse
UserData --> PutWalletPreferencesRequest
UserData --> PutWalletPreferencesResponse
UserData --> ListWalletSignersRequest
UserData --> ListWalletSignersResponse
UserData --> PutWalletSignerRequest
UserData --> PutWalletSignerResponse
UserData --> DeleteWalletSignerRequest
UserData --> DeleteWalletSignerResponse
UserData --> ListSessionsRequest
UserData --> ListSessionsResponse
UserData --> PutSessionRequest
UserData --> PutSessionResponse
UserData --> DeleteSessionRequest
UserData --> DeleteSessionResponse
UserData --> ListContactsRequest
UserData --> ListContactsResponse
UserData --> PutContactRequest
UserData --> PutContactResponse
UserData --> DeleteContactRequest
UserData --> DeleteContactResponse
UserData --> ListWatchedWalletsRequest
UserData --> ListWatchedWalletsResponse
UserData --> PutWatchedWalletRequest
UserData --> PutWatchedWalletResponse
UserData --> DeleteWatchedWalletRequest
UserData --> DeleteWatchedWalletResponse
UserData --> ListDiscoverFavoritesRequest
UserData --> ListDiscoverFavoritesResponse
UserData --> PutDiscoverFavoriteRequest
UserData --> PutDiscoverFavoriteResponse
UserData --> DeleteDiscoverFavoriteRequest
UserData --> DeleteDiscoverFavoriteResponse
UserData --> ListDiscoverHistoryRequest
UserData --> ListDiscoverHistoryResponse
UserData --> PutDiscoverHistoryRequest
UserData --> PutDiscoverHistoryResponse
UserData --> DeleteDiscoverHistoryRequest
UserData --> DeleteDiscoverHistoryResponse
UserData --> ListTokenFavoritesRequest
UserData --> ListTokenFavoritesResponse
UserData --> PutTokenFavoriteRequest
UserData --> PutTokenFavoriteResponse
UserData --> DeleteTokenFavoriteRequest
UserData --> DeleteTokenFavoriteResponse
Wallet --> WalletPreferences
File-Level Changes
| Change | Details | Files |
|---|---|---|
| Expand userdata WebRPC schema, client interface, and TypeScript types to support wallet preferences, signers, sessions, contacts, watched wallets, discover data, and token favorites. | Update generated schema metadata hash to match new RIDL schemaExtend UserDataClient with CRUD-style methods for wallet preferences, wallet signers, sessions, contacts, watched wallets, discover favorites/history, and token favoritesIntroduce new schema types and props (Version, RuntimeStatus, WalletPreferences, WalletSigner, Contact, WatchedWallet, DiscoverFavorite/History, TokenFavorite, and related *Props interfaces)Define request/response interfaces for the new RPC methodsAdd corresponding UserData class methods that encode requests, call fetch with appropriate method names, and decode responses | packages/services/userdata/src/userdata.gen.ts |
| Optimize dapp-client transaction handling by caching the last signed call and reusing it when identical calls are sent shortly after, while simplifying permission error handling. | Add lastSignedCallCache state to ChainSessionManager to store fingerprinted calls, signed payload, and creation timestampRemove special-case retry logic for expired signer errors in hasPermission, now treating signer resolution failures as permission failuresCache signed calls in getTransactionsFeeOptions using a call fingerprint, with a short TTL, before querying relayer fee optionsReuse cached signed call in sendTransact when the call set matches the cached fingerprint, otherwise rebuild and signImplement _getCachedSignedCall with TTL-based invalidation and fingerprint equality checkImplement _fingerprintCalls to JSON-stringify normalized call fields (to, value, data, gasLimit, delegateCall, onlyFallback, behaviorOnError) with error handling | packages/wallet/dapp-client/src/ChainSessionManager.ts |
| Publish 3.0.0-beta.12 across core, wallet, services, and utils packages with notes about dapp connector fixes and dependency bumps. | Add 3.0.0-beta.11 and 3.0.0-beta.12 entries to multiple package CHANGELOGs describing beta and dapp connector fixesBump package.json versions for services, wallet, and abi-related packages from 3.0.0-beta.10 to 3.0.0-beta.12Add new changeset files describing patch releases for all affected packages (3.0.0 beta and beta.12 with dapp connector fixes) | packages/wallet/wdk/CHANGELOG.mdpackages/wallet/dapp-client/CHANGELOG.mdpackages/wallet/core/CHANGELOG.mdpackages/services/relayer/CHANGELOG.mdpackages/services/api/CHANGELOG.mdpackages/services/builder/CHANGELOG.mdpackages/services/guard/CHANGELOG.mdpackages/services/identity-instrument/CHANGELOG.mdpackages/services/indexer/CHANGELOG.mdpackages/services/marketplace/CHANGELOG.mdpackages/services/metadata/CHANGELOG.mdpackages/services/userdata/CHANGELOG.mdpackages/utils/abi/CHANGELOG.mdpackages/wallet/primitives/CHANGELOG.mdpackages/services/api/package.jsonpackages/services/builder/package.jsonpackages/services/guard/package.jsonpackages/services/identity-instrument/package.jsonpackages/services/indexer/package.jsonpackages/services/marketplace/package.jsonpackages/services/metadata/package.jsonpackages/services/relayer/package.jsonpackages/services/userdata/package.jsonpackages/utils/abi/package.jsonpackages/wallet/core/package.jsonpackages/wallet/dapp-client/package.jsonpackages/wallet/primitives/package.jsonpackages/wallet/wdk/package.json.changeset/bright-pots-hope.md.changeset/free-tips-switch.md |
Interacting with Sourcery
- Trigger a new review: Comment
@sourcery-ai reviewon the pull request. - Continue discussions: Reply directly to Sourcery's review comments.
- Generate a GitHub issue from a review comment: Ask Sourcery to create an
issue from a review comment by replying to it. You can also reply to a
review comment with
@sourcery-ai issueto create an issue from it. - Generate a pull request title: Write
@sourcery-aianywhere in the pull request title to generate a title at any time. You can also comment@sourcery-ai titleon the pull request to (re-)generate the title at any time. - Generate a pull request summary: Write
@sourcery-ai summaryanywhere in the pull request body to generate a PR summary at any time exactly where you want it. You can also comment@sourcery-ai summaryon the pull request to (re-)generate the summary at any time. - Generate reviewer's guide: Comment
@sourcery-ai guideon the pull request to (re-)generate the reviewer's guide at any time. - Resolve all Sourcery comments: Comment
@sourcery-ai resolveon the pull request to resolve all Sourcery comments. Useful if you've already addressed all the comments and don't want to see them anymore. - Dismiss all Sourcery reviews: Comment
@sourcery-ai dismisson the pull request to dismiss all existing Sourcery reviews. Especially useful if you want to start fresh with a new review - don't forget to comment@sourcery-ai reviewto trigger a new review!
Customizing Your Experience
Access your dashboard to:
- Enable or disable review features such as the Sourcery-generated pull request summary, the reviewer's guide, and others.
- Change the review language.
- Add, remove or edit custom review instructions.
- Adjust other review settings.
Getting Help
- Contact our support team for questions or feedback.
- Visit our documentation for detailed guides and information.
- Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.
Originally posted by @sourcery-ai[bot] in https://github.com/Dargon789/sequence.js/issues/265#issuecomment-3843098288