Conversation
…very - add asset-core registry/plugin primitives (DeviceId, AssetPlugin, createAssetRegistry) - move lattice signer implementations into each asset package and export `latticePlugin` - add SDK static default manifest + single discovery path for built-in assets - replace `sdk/src/assets/lattice.ts` with runtime registry/context/discovery modules - wire `setup()` for `autoRegisterAssets`, `defaultDevice`, and `assetPlugins` overrides - route signing/address helpers through `useAsset()` adapters with cache invalidation - add unit tests for registry, discovery, default manifest, and setup plugin behavior
commit: |
Replace truthy checks with numeric validation in lattice device context guards for `cosmos`, `evm`, and `solana` assets. This prevents valid enum values like `0` (for example `HASHES.NONE` / `CURVES.SECP256K1`) from being treated as missing and throwing false "requires EXTERNAL constants" runtime errors.
6053437 to
b184fe8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b184fe8dbc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| params: BtcGetAddressParams = {}, | ||
| ): Promise<Address> => { | ||
| const path = resolvePath(params, options); | ||
| return signer.getAddress(path, { format: params.format }); |
There was a problem hiding this comment.
Apply resolved BTC format in single-address lookup
getAddress forwards only params.format, so adapter-level defaults (options.format) and the module’s own format resolution are skipped for single-address calls. In practice, getAddress()/getAccount() can ignore the configured BTC format while getAddresses() honors it, leading to inconsistent address type selection for the same adapter configuration.
Useful? React with 👍 / 👎.
📝 Summary
@gridplus/sdk.btc,evm,solana,cosmos) and exportslatticePluginfrom each package.setup(); optional custom plugins can be passed viasetup({ chainPlugins }).🔧 Context / Implementation
@gridplus/chain-core(DeviceId,ChainPlugin,createChainRegistry, resolver helpers).packages/sdk/src/chains/registry.tspackages/sdk/src/chains/context.tspackages/sdk/src/chains/discovery.tspackages/sdk/src/chains/defaultManifest.tssetup()to support:autoRegisterChains(defaulttrue)defaultDevice(default'lattice')chainPlugins(validated; duplicate-in-input throws; built-in key can be overridden)useChain(...)runtime resolution with lazy signer/adapter creation and cache invalidation.🧪 Test Plan
cd packages/sdk && npm run typecheckcd packages/sdk && npm run test-unitsetup()auto-registers built-ins (btc,evm,solana,cosmos) by default.setup({ autoRegisterChains: false, chainPlugins: [...] })registers only provided plugins.setup({ chainPlugins })can override a built-in(chainId, device)key.Expected result: all checks pass and runtime behavior matches previous helper APIs while using plugin-based chain resolution.
🖼️ Screenshots (if applicable)
Chain Registry Architecture (SDK + Chain Packages)
1) Component View
flowchart LR App["Consumer App"] --> Setup["setup(...)"] App --> Helpers["api/signing.ts\napi/addresses.ts"] subgraph SDK["@gridplus/sdk"] Setup --> RuntimeCfg["configureChainRuntime(...)"] Setup --> DiscoverCall["discoverAndRegisterChains({force:true})"] Setup --> CustomReg["registerConfiguredChainPlugins(...)"] Helpers --> UseChain["useChain(chainId, options)"] UseChain --> Registry["chains/registry.ts"] Registry --> Ctx["createDeviceContext()"] Ctx --> Runtime["queue/getClient/constants/services"] DiscoverCall --> Discovery["chains/discovery.ts"] Discovery --> Manifest["chains/defaultManifest.ts"] end subgraph Core["@gridplus/chain-core"] CoreRegistry["createChainRegistry()\nChainPlugin + DeviceId + resolve()"] end subgraph Chains["@gridplus/{btc,evm,solana,cosmos}"] Btc["btc/src/devices/lattice.ts\nlatticePlugin"] Evm["evm/src/devices/lattice.ts\nlatticePlugin"] Sol["solana/src/devices/lattice.ts\nlatticePlugin"] Cos["cosmos/src/devices/lattice.ts\nlatticePlugin"] Cadix["future: */src/devices/cadix.ts\ncadixPlugin"] end Registry --> CoreRegistry Manifest --> Btc Manifest --> Evm Manifest --> Sol Manifest --> Cos CustomReg --> Cadix Registry --> Plugin["resolved plugin (chainId:device)"] Plugin --> Signer["createSigner(context)"] Signer --> Adapter["module.create(...) or createAdapter(...)"] Adapter --> Device["Client calls via queue(...)"]2) Runtime Flow (Setup + Use)
sequenceDiagram participant App participant Setup as setup() participant Registry as chains/registry.ts participant Discovery as chains/discovery.ts participant Manifest as defaultManifest.ts participant API as signing/addresses helpers participant Plugin as ChainPlugin participant Device as Client App->>Setup: setup({autoRegisterChains, defaultDevice, chainPlugins}) Setup->>Registry: configureChainRuntime(..., resetCache=true) alt autoRegisterChains != false Setup->>Registry: discoverAndRegisterChains({force:true}) Registry->>Discovery: discover(registerFn) Discovery->>Manifest: iterate DEFAULT_CHAIN_PLUGINS loop each default plugin Discovery->>Registry: register if missing end end opt chainPlugins provided Setup->>Registry: unregisterChain(key) if existing Setup->>Registry: registerChainPlugin(plugin) // override end App->>API: sign*/fetch* request API->>Registry: useChain(chainId, {device?, adapterOptions?}) Registry->>Registry: resolve(chainId, device/defaultDevice) alt cache miss or generation changed Registry->>Plugin: createSigner(createDeviceContext()) Plugin-->>Registry: signer Registry->>Plugin: createAdapter(...) or module.create(...) Plugin-->>Registry: adapter else cache hit Registry-->>Registry: reuse signer + adapter end Registry-->>API: adapter API->>Device: queue(client => sign/getAddresses/...) Device-->>API: result3) Registry + Cache Lifecycle
stateDiagram-v2 [*] --> RuntimeConfigured: configureChainRuntime() RuntimeConfigured --> BuiltInsRegistered: discoverAndRegisterChains()\n(autoRegisterChains=true) RuntimeConfigured --> RuntimeConfigured: discoverAndRegisterChains()\n(autoRegisterChains=false) BuiltInsRegistered --> BuiltInsRegistered: discoverAndRegisterChains()\n(idempotent) BuiltInsRegistered --> Overridden: setup({chainPlugins}) override Overridden --> Overridden: useChain() cache hit Overridden --> CacheRebuilt: useChain() cache miss CacheRebuilt --> Overridden: adapter memoized Overridden --> RuntimeConfigured: invalidateChainCache()\nunregisterChain()\nsetup(resetCache=true) RuntimeConfigured --> [*]4) Behavior Matrix
autoRegisterChains: truesetup().autoRegisterChains: falsechainPluginscollides with built-in keychainPluginsinputsetup()throws.useChainunresolved chain/device5) Source Map
packages/sdk/src/api/setup.tspackages/sdk/src/api/signing.tspackages/sdk/src/api/addresses.tspackages/sdk/src/chains/registry.tspackages/sdk/src/chains/discovery.tspackages/sdk/src/chains/defaultManifest.tspackages/sdk/src/chains/context.tspackages/chains/chain-core/src/index.tspackages/chains/btc/src/devices/lattice.tspackages/chains/evm/src/devices/lattice.tspackages/chains/solana/src/devices/lattice.tspackages/chains/cosmos/src/devices/lattice.ts