Conversation
bucket-bot
left a comment
There was a problem hiding this comment.
Code review
No issues found. Checked for bugs and CLAUDE.md compliance.
Noted: this is a large refactor (+2768/-1342), but the async initialization flow, on-chain config adapter, and new e2e/unit coverage are consistent.
🤖 Generated with Rex (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code review
Found 2 issues:
queryAllConfigcan return a partial config after RPC/object parse errors, and initialization still succeeds. This creates a fail-open path where required package IDs/object refs become empty strings/default refs and later transaction builders produce malformed targets/refs instead of failing at init time. Please fail fast by validating required sections/keys (e.g. packageConfig/oracleConfig/objectConfig + required fields) and throw when any mandatory object inid_vectorcannot be resolved.
bucket-protocol-sdk/src/utils/bucketConfig.ts
Lines 136 to 176 in 57e9475
initialize({ configOverrides })stores overrides on the instance, butrefreshConfig()does not preserve them when called without args. A later refresh silently drops prior overrides (e.g. customPRICE_SERVICE_ENDPOINT) and changes runtime behavior unexpectedly. Consider defaulting tooverrides ?? this.configOverridesand updatingthis.configOverrideswhen explicit overrides are provided.
bucket-protocol-sdk/src/client.ts
Lines 114 to 164 in 57e9475
🤖 Generated with Rex (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code Review
Found 4 issues worth addressing:
1. initialSharedVersion: 0 fallback in toSharedObjectRef will break transactions (confidence: 88)
When json is a plain string (objectId only), the function defaults to initialSharedVersion: 0. Sui requires the correct initial shared version for shared object references in PTBs — using 0 here will silently produce invalid transactions at runtime. If only an objectId string arrives from on-chain JSON, the code should either throw or fetch the actual version separately.
bucket-protocol-sdk/src/utils/configAdapter.ts
Lines 19 to 24 in 57e9475
2. Race condition in ensureConfig — parallel calls before config loads will trigger multiple RPC fetches (confidence: 82)
private async ensureConfig(): Promise<void> {
if (!this._config) {
await this.refreshConfig(this.configOverrides); // no in-flight guard
}
}If two async SDK methods are called concurrently before config is initialized (e.g. client.getOraclePrices() and client.getVaultObjectInfo() in parallel), both see _config === null and trigger separate queryAllConfig RPC calls. Fix with a cached promise:
private _configPromise: Promise<void> | null = null;
private async ensureConfig(): Promise<void> {
if (!this._config) {
this._configPromise ??= this.refreshConfig(this.configOverrides).finally(() => {
this._configPromise = null;
});
await this._configPromise;
}
}bucket-protocol-sdk/src/client.ts
Lines 95 to 99 in 57e9475
3. refreshConfig() called without args silently drops configOverrides (confidence: 82)
initialize() stores configOverrides on the instance, and ensureConfig() correctly passes them through. But refreshConfig() is a public method — if a consumer calls client.refreshConfig() directly (without overrides), the stored overrides are lost and the config reverts to pure on-chain values. Consider making refreshConfig always apply the stored this.configOverrides as defaults:
async refreshConfig(overrides?: Partial<ConfigType>): Promise<void> {
const onchainConfig = await queryAllConfig(this.suiClient, this.network);
this._config = convertOnchainConfig(onchainConfig, overrides ?? this.configOverrides);
}bucket-protocol-sdk/src/client.ts
Lines 102 to 105 in 57e9475
4. Previously synchronous public getters are now async — breaking API change without semver bump (confidence: 85)
getUsdbCoinType(), getAllOracleCoinTypes(), getAllCollateralTypes(), getAggregatorObjectInfo(), getVaultObjectInfo(), getSavingPoolObjectInfo(), getPsmPoolObjectInfo() were all synchronous before. They now return Promise<T>. Any existing consumer using the return value directly (e.g. const t = client.getUsdbCoinType()) now gets a Promise<string> instead of a string — a silent runtime break unless TypeScript is strict. This PR should either bump the major version or provide deprecation shims. At minimum, the PR description and CHANGELOG should call this out explicitly as a breaking change.
bucket-protocol-sdk/src/client.ts
Lines 156 to 165 in 57e9475
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Re-review (on-chain config request path)
這版修正方向很對(fail-fast on fetch/parse、ensureConfig race、refresh override 保留、shared version enrichment 都補上了 👍)。
我再看 queryAllConfig 的請求邏輯後,還有一個高風險邊界:
- 目前仍未驗證「必要 config section 是否齊全」
queryAllConfig 結尾直接 return result,但沒有檢查 packageConfig / oracleConfig / objectConfig 是否都存在。若 RPC 回傳不完整(例如 id_vector 少項、未知 type 被 warn 後略過、或服務端只回部分 objects),流程仍會成功返回,後續 convertOnchainConfig 會用空字串/預設值填充,變成延遲失敗。
建議在返回前加 required-section validation(至少三個核心 section + 可選地驗證關鍵欄位非空),缺任一個就 throw,讓初始化在入口就 fail-fast。
參考位置:
bucket-protocol-sdk/src/utils/bucketConfig.ts
Lines 146 to 178 in 71d7db9
🤖 Generated with Rex (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code Review (Round 2)
四個問題都有對應處理,整體方向正確。剩下一個需要留意:
✅ 已修 — queryAllConfig fail-fast
continue 改成 throw,partial config 問題解決。對應測試也更新了,Good。
✅ 已修 — refreshConfig 保留 overrides
overrides ?? this.configOverrides ✓
✅ 已修 — enrichSharedObjectRefs 補 initialSharedVersion
深克隆 + batch fetch + 正確 apply,邏輯清楚。
_configInitPromise 失敗後無法重試 (confidence: 82)
private async ensureConfig(): Promise<void> {
if (this._config) return;
if (!this._configInitPromise) {
this._configInitPromise = this.refreshConfig(this.configOverrides);
}
await this._configInitPromise; // ← 若 reject,下次仍 await 同一個 rejected promise
}_configInitPromise 失敗後永遠不會被清除。只要 refreshConfig 因為網路閃斷 throw 一次,this._config 仍是 null、this._configInitPromise 是 rejected promise,後續所有 ensureConfig 呼叫都會吃到那個舊的 rejection,client 永久不可用,無法重試。建議在 finally 清除:
private async ensureConfig(): Promise<void> {
if (this._config) return;
if (!this._configInitPromise) {
this._configInitPromise = this.refreshConfig(this.configOverrides)
.finally(() => { this._configInitPromise = null; });
}
await this._configInitPromise;
}bucket-protocol-sdk/src/client.ts
Lines 119 to 126 in 71d7db9
其他部分 LGTM,測試覆蓋也到位。
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Re-review (latest push)
queryAllConfig 這次補的 required-section / required-field validation 看起來 OK,方向正確 👍
目前還有一個 blocker 仍在:
_configInitPromise在初始化失敗後沒有 reset
ensureConfig() 會快取 this._configInitPromise,但若第一次 refreshConfig() reject(例如暫時性 RPC/network error),這個 rejected promise 會一直留著。之後所有 ensureConfig() 都會直接 await 同一個 rejected promise,client 無法自動重試,等於永久卡死。
建議在設置 promise 時加 finally 清理:
if (!this._configInitPromise) {
this._configInitPromise = this.refreshConfig(this.configOverrides)
.finally(() => {
this._configInitPromise = null;
});
}
await this._configInitPromise;參考位置:
bucket-protocol-sdk/src/client.ts
Lines 124 to 130 in 10e7218
🤖 Generated with Rex (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code Review (Round 3)
Required-section 驗證加了,邏輯清楚,測試覆蓋也很完整。
但上一輪指出的 _configInitPromise 問題還沒修到:
_configInitPromise 失敗後未清除,client 無法從網路錯誤中恢復 (confidence: 82)
// src/client.ts — 目前狀態
private async ensureConfig(): Promise<void> {
if (this._config) return;
if (!this._configInitPromise) {
this._configInitPromise = this.refreshConfig(this.configOverrides);
// ← 沒有 finally 清除
}
await this._configInitPromise;
}refreshConfig 因網路閃斷 reject 一次後,_configInitPromise 永遠保留那個 rejected promise,後續所有 ensureConfig 呼叫都重新 await 同一個已失敗的 promise,client 永久不可用。Fix 一行:
this._configInitPromise = this.refreshConfig(this.configOverrides)
.finally(() => { this._configInitPromise = null; });bucket-protocol-sdk/src/client.ts
Lines 119 to 126 in 10e7218
其他部分(required-section 驗證、測試覆蓋)全部 LGTM,修完這個就可以 approve 了。
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Re-review
Latest commit resolves the remaining blocker.
ensureConfig()now clears_configInitPromiseon failure, so transient init errors no longer permanently poison the client.- Added retry-focused unit coverage (
clears _configInitPromise on failure so subsequent calls can retry). - Previously discussed on-chain config request-path fixes (fail-fast sub-object handling + required section validation) are still in place.
LGTM. Approving.
🤖 Generated with Rex (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
所有問題都解決了:
- ✅
queryAllConfigfail-fast(不再回傳 partial config) - ✅ required-section 驗證
- ✅
refreshConfig保留configOverrides - ✅
ensureConfigrace condition - ✅
initialSharedVersionenrichment - ✅
_configInitPromise失敗後清除,允許重試
LGTM 🚀
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Re-review (BucketClient initialization changes)
Found 1 issue:
initialize({ configObjectId })andrefreshConfig()now have inconsistent config source behavior. Initial load can come from a custom entry object, butrefreshConfig()always callsqueryAllConfig(this.suiClient, this.network)and drops that custom source. After first refresh, the client may silently switch back to default network config, which is risky for test/custom deployments. Please persistconfigObjectIdon the instance and reuse it inrefreshConfig().
bucket-protocol-sdk/src/client.ts
Lines 104 to 160 in 517121e
🤖 Generated with Rex (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code Review (Round 5 — 初始化重構)
這次改法方向完全正確,大幅簡化了複雜度。
✅ 設計改進
- Constructor 改成
config必填 → 徹底消除 lazy init 邏輯(ensureConfig、_configInitPromise全刪) - Getter 全部回到 sync (
getConfig(),getUsdbCoinType()等) → 解決之前的 breaking API change 問題 initialize()加了configObjectId和config注入點 → 方便測試,不用打真實 RPCqueryAllConfig多一個 optionalconfigObjectId參數 → 設計一致
整體 LGTM 🚀
initialize() 的 configParam 路徑沒有套用 configOverrides:
if (configParam) {
config = await enrichSharedObjectRefs(configParam, client);
// ← configOverrides 這裡沒有 apply,但 bc.configOverrides 還是設了
} else {
config = convertOnchainConfig(onchainConfig, configOverrides); // ← 這裡有套用
config = await enrichSharedObjectRefs(config, client);
}
const bc = new BucketClient({ suiClient: client, network, config });
bc.configOverrides = configOverrides;結果:傳 config + configOverrides 給 initialize() 時,初始 config 不含 overrides,但之後呼叫 refreshConfig() 會套用。行為有點不一致。
這個路徑主要給測試用,影響面小;但如果這是 intentional,建議在 JSDoc 補一句說明,避免誤用。
Non-blocking,可 merge。
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
✅ configObjectId 正確存在 instance、refreshConfig() 也傳進去了,行為一致。JSDoc 也補清楚了(包含 config + configOverrides 的行為說明)。測試直接驗 queryAllConfig 被呼叫時帶了正確的 configObjectId,覆蓋到位。
LGTM,可以 merge 🚀
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Re-review
Latest commit addresses the remaining initialization-path concern.
BucketClientnow persistsconfigObjectIdfrominitialize().refreshConfig()reuses that sameconfigObjectId, so config source no longer silently switches back to default entry config.- Unit coverage was added for this exact behavior (
refreshConfig() uses configObjectId from initialize). - JSDoc clarifications around
config+configOverridesbehavior are also helpful.
LGTM. Approving.
🤖 Generated with Rex (OpenClaw)
PR 變更摘要核心變更
其他
|
bucket-bot
left a comment
There was a problem hiding this comment.
Code Review — 移除包裝層重構
✅ LGTM
private _config+ getter 合併成直接的private configfield,更簡潔- 所有
_method()private 包裝全部移除,邏輯直接 inline 到 public method — 沒有漏掉任何調用點 - 內部互呼(
aggregatePrices、getAccountPositions等)已全部更新為直接呼叫 public 方法,行為一致 - README
flashBurn參數修正(flashMintReceipt)也是正確的
無新問題引入,可以 merge 🚀
🤖 Generated with Jarvis (OpenClaw)
2329df6 to
f94f48c
Compare
bucket-bot
left a comment
There was a problem hiding this comment.
Code review
Found 1 issue:
- Silent failure in
enrichSharedObjectRefs— whengetObjectsreturns anErrorfor any object, the error is silently skipped withcontinue. The ref keepsinitialSharedVersion: 0, which will cause PTB rejection at transaction time with no useful error message pointing back to the version enrichment step.
bucket-protocol-sdk/src/utils/configAdapter.ts
Lines 304 to 310 in f94f48c
Consider throwing (or at least logging a warning) when an object lookup fails during enrichment:
if (obj instanceof Error) {
console.warn(`enrichSharedObjectRefs: failed to fetch object for version enrichment: ${obj.message}`);
continue;
}This makes the failure surface immediately instead of silently building a broken config.
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code review
Found 1 issue:
Silent error swallowing in enrichSharedObjectRefs — fetch failures leave refs with initialSharedVersion: 0
bucket-protocol-sdk/src/utils/configAdapter.ts
Lines 344 to 349 in f94f48c
When client.getObjects() returns an Error for one of the shared-object refs, the loop silently skips it and the ref stays at initialSharedVersion: 0. Sui validators will reject any PTB that references a shared object with initialSharedVersion: 0, producing a confusing low-level error at tx submission time instead of a clear SDK error at initialization.
Suggest either:
// Option A — throw fast (preferred)
if (obj instanceof Error) {
throw new Error(`Failed to fetch shared object ${obj.objectId} for version enrichment: ${obj.message}`);
}
// Option B — warn and let callers discover the issue
if (obj instanceof Error) {
console.warn(`enrichSharedObjectRefs: failed to fetch ${obj.objectId}, initialSharedVersion will be 0: ${obj.message}`);
continue;
}Everything else looks solid. The on-chain config migration is clean — queryAllConfig fail-fasts on required sections, the configOverrides merge order is correct, and the BucketClient.initialize() async factory pattern is a good API design. The Option<T> → bcs.option() and module 'object' casing fixes in _generated/utils/index.ts are correct bug fixes.
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Fix confirmed ✅
The loop was refactored to for (let i = 0; i < objects.length; i++) so objectIds[i] is accessible when logging. The console.warn now surfaces the objectId and error message, making any future enrichment failures debuggable. Reasonable choice to warn-and-continue rather than throw (lets the SDK still function for other refs).
No further issues found. LGTM.
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code review (latest commit 24295a9)
Found 1 issue:
Missing case 'Unihouse' in getDerivativePrice switch → runtime throw for Unihouse derivatives
bucket-protocol-sdk/src/client.ts
Lines 1068 to 1088 in 24295a9
The dk mapping explicitly includes 'Unihouse' → 'gCoin':
derivative_kind === 'GCoin' || derivative_kind === 'gCoin' || derivative_kind === 'Unihouse'
? 'gCoin'But the switch (derivative_kind) below only has case 'gCoin': and case 'GCoin': — no case 'Unihouse':. So any coin with derivative_kind === 'Unihouse' will fall through to default: throw.
Fix:
case 'gCoin':
case 'GCoin':
case 'Unihouse': { // ← add this
...
}Everything else in this refactor looks correct. The type alignment with generated BCS types (SharedObjectRef[''], initialSharedVersion: string, snake_case field names, discriminated union shape for AggregatorObjectInfo / PriceConfigInfo) is clean and consistent throughout configAdapter.ts, client.ts, and tests.
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Fix confirmed ✅ — case 'Unihouse': added to the same block as gCoin/GCoin, consistent with the dk mapping. No further issues found. LGTM.
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code review
Found 1 issue:
- Wrong field name in test —
config.PSM_OBJSshould beconfig.PSM_POOL_OBJS(field was renamed in this PR but the test wasn't updated)
bucket-protocol-sdk/test/e2e/all-query-outputs.test.ts
Lines 131 to 133 in 7c47e14
config.PSM_OBJS doesn't exist on ConfigType — the correct field is PSM_POOL_OBJS. The ?? {} fallback silently hides the typo, so firstPsmCoinType will always fall back to usdcCoinType instead of reading from actual config.
Everything else looks solid. The on-chain config migration is well-structured:
- Fail-fast validation in
queryAllConfig✅ enrichSharedObjectRefsdedup + warn-on-error is reasonable ✅- snake_case field rename (
rewarder_id,reward_type, etc.) is consistent across client + types ✅ get_realtime_reward_amountrefactor for saving pool rewards (avoids PTB ref limitation) ✅getUsdbSupplyswitch from PTB simulation tostateService.getCoinInfo✅- Error handling upgraded from silent-empty to explicit throws ✅
🤖 Generated with Jarvis (OpenClaw)
bucket-bot
left a comment
There was a problem hiding this comment.
Code review
The fix looks good — PSM_OBJS → PSM_POOL_OBJS is corrected, and the new assertions (toBeGreaterThan(0) for PSM/saving/collateral pools) properly fail-fast instead of silently falling back. No further issues found.
🤖 Generated with Jarvis (OpenClaw)
…ns, savings, rewards Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
…ides, ensureConfig race, initialSharedVersion enrichment - queryAllConfig: fail-fast on sub-object fetch/parse errors instead of returning partial config - refreshConfig: preserve configOverrides when called without args - ensureConfig: use cached promise to prevent concurrent RPC calls - enrichSharedObjectRefs: fetch initialSharedVersion for refs with objectId-only (fixes PTB tx failure) - Add unit tests for all four fixes Made-with: Cursor
…onfig) before queryAllConfig return - Add required-section and key-field validation to fail-fast on incomplete RPC response - Throw when any required section is missing or key field is empty - Add unit tests for validation failure cases Made-with: Cursor
- bucketConfig: missing oracleConfig/objectConfig, empty pyth_state_id, empty treasury_obj - configAdapter: empty objectId skip, deduplication, non-Shared owner skip, no-refs case - client: explicit refreshConfig overrides, ensureConfig when config already loaded Made-with: Cursor
…edge tests
- client: clear _configInitPromise in ensureConfig catch so subsequent calls can retry
- client: fix mockImplementation type for queryAllConfig
- test: add reverse tests (enrichSharedObjectRefs immutability, refreshConfig({}), no retry on success)
- test: add expect.fail pattern for required section throw case
- prettier
Made-with: Cursor
- Add await to all async method calls (getAllCollateralTypes, build*, flashMint/flashBurn, getAggregatorObjectInfo, getVaultObjectInfo, etc.) - Update version 1.2.8 -> 2.0.1 - Fix Example Project link (client.test.ts -> test/e2e/ directory) - Constructor config is optional (lazy-load from chain) Made-with: Cursor
Made-with: Cursor
…API consistency with main Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
… config+configOverrides Made-with: Cursor
Made-with: Cursor
- Replace private _config + getter with direct config field (match main style) - Fix flashBurn param: use flashMintReceipt in README Pattern 2 - Update example project path to actual e2e test files - Bump version in README to 2.0.1 Made-with: Cursor
…config - Replace _generated_onchain_config with _generated/bucket_onchain_config - Update BucketOnchainConfig to use raw on-chain JSON shape (Record<string, unknown>) - bucketConfig now defines local types; generated modules export BCS structs, not TS types - Add bucket_onchain_config bindings (copied from external source) - Remove codegen tooling (sui-codegen.config.ts, scripts, @mysten/codegen) - Add sui-codegen.config.ts to .gitignore, pnpm-lock.yaml to .prettierignore Made-with: Cursor
…jectRefs Silent failure left initialSharedVersion at 0 when object fetch failed, causing PTB to fail at execution with no clear indication of the cause. Now logs objectId and error message for easier debugging. Made-with: Cursor
…ated types
- Use SharedObjectRef, RewarderInfo, PsmPoolObjectInfo from generated $inferType
- Switch config parsing to snake_case and enum shapes ({ Pyth: {...} }, { SCOIN: {...} }, etc.)
- Keep manual types for AggregatorObjectInfo, PriceConfigInfo (MoveEnum requires $kind; we parse from JSON)
- Keep manual types for VaultObjectInfo, SavingPoolObjectInfo (optional rewarders/reward when empty)
- Change initialSharedVersion to string type to match BCS schema
- Update client.ts, configAdapter, and all related tests
Made-with: Cursor
On-chain derivative_kind can be 'Unihouse'; dk mapping already maps it to 'gCoin', but the switch lacked the case and threw Unsupported derivative kind. Made-with: Cursor
…rnType - Replace simulateTransaction + borrow_cap_mut with stateService.getCoinInfo - PTB cannot pass &mut references between commands; SDK v2 validates and rejects - Tighten test assertion: expect supply > 0 (was >= 0, masked failures) Made-with: Cursor
…ls until realtime_reward_amount_by_manager) Made-with: Cursor
…s, unit tests - Add all-query-outputs.test.ts with getAccountBorrowRewards using coinTypesWithRewarders - Add unit tests for client, bucketConfig, configAdapter, resolvers, transaction - Extend cdp.test, oracle.test Note: getAccountSavingPoolRewards / getUserSavings / getAccountSavings tests remain skipped — not yet fixed (awaiting contract upgrade for PTB reference limitation). Made-with: Cursor
- Replace get_rewarder + realtime_reward_amount with single get_realtime_reward_amount call to avoid PTB reference limitation (references cannot be passed between commands) - Simplify response parsing: one result per reward type instead of two - Re-enable savings-rewards e2e tests (getUserSavings, getAccountSavings, getAccountSavingPoolRewards) now that contract upgrade is deployed - Remove pool: 'forks' from vitest config Made-with: Cursor
Made-with: Cursor
- Assert required config (PSM_POOL_OBJS, SAVING_POOL_OBJS, collateral types) at start; fail fast if missing - Add runOrSkip for APIs that need optional config (e.g. vault with rewarders); record explicit skip reason - Use config-derived values directly instead of ?? fallbacks (firstPsmCoinType, firstLpType, firstCoinType) - Fix PSM_OBJS typo → PSM_POOL_OBJS - Mark skipped APIs with ⊘ in report output Made-with: Cursor
- cdp: use it.skipIf for buildClosePositionTransaction when test account has no SUI position - savings-rewards: use it.skipIf for getAccountBorrowRewards when API returns no SUI entry - vaults: assert flowRates non-empty when SUI vault has rewarders - rewards: assert reward balance changes when buildClaimBorrowRewards returns coins - all-query-outputs: add aggregateBasicPrices with multiple Pyth coin types (4) Made-with: Cursor
…Type); add onchain-config tests + lint fix Made-with: Cursor
c37fb58 to
fbeb4a0
Compare
Testing Workflow Improvements
test:unit,test:e2e,test:coverage, etc.) inpackage.jsonand documented their usage inCLAUDE.mdto allow running unit and e2e tests separately and improve coverage reporting.@vitest/coverage-v8and related dependencies to support coverage reporting, reflected in bothpackage.jsonandpnpm-lock.yaml.CLAUDE.md, distinguishing between fast local unit tests and e2e tests that interact with mainnet RPC, with guidance on avoiding RPC rate limits.On-Chain Config Integration & SDK Caching
Added
configAdaptor.tsconfigAdaptor.tsto adapt on-chain config objects into the SDK’s internal config structure.Added
bucketConfig.tsbucketConfig.tsas a dedicated module responsible for fetching on-chain config data.Automatic Config Validation & Refetch
Documentation Updates
Updated
README.mdandCLAUDE.mdto standardize initialization via:Documented that
BucketClient.initialize():Clarified best practices for client initialization and config lifecycle management.
Dependency Management
Updated
pnpm-lock.yamlwith new packages required for coverage and testing, including:@vitest/coverage-v8