-
Notifications
You must be signed in to change notification settings - Fork 28
Allowing signer methods in xion.js - Wallet/Turnkey support #314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Allowing signer methods in xion.js - Wallet/Turnkey support #314
Conversation
🦋 Changeset detectedLatest commit: a521968 The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
base version already works through dashboard here: https://github.com/burnt-labs/xion-dashboard-app/pull/278 This PR is to disintermediate the dashboard. |
…unt-management packages
…need a ton more cleanup, demi app needs through check on, need to make more general utillities around the signing behaviour, need to add ed25119 signing method, need to fix the window.... calling for wallets, persitency for sessions works but local signer method with turnkey is still funky.
88a824c to
2842c25
Compare
…C fallback strat for checking accounts
…direct mode barring grant warnings and removing logs. finalize demo app and split abstraxion providers, REMOVE direct signer as implementation eas bad
…query indexer, solve daodao indexer url issue, correctly manage client creation, simplify turnkey create wallet, handle double logout
…on.js for better type safety
…Removed api specific authenticator type
- Remove direct mode (CosmosWalletConnector, EthereumWalletConnector) - Add controller pattern (BaseController, RedirectController, SignerController) - Add orchestrator pattern with flow modules (accountConnection, grantCreation, redirectFlow, sessionRestoration) - Add state machine for predictable state management - Reorganize account-management and grants code structure - Move SignerConfig to abstraxion-core (fix circular dependency) - Add signature utilities to signers package - Remove old authentication components and hooks - Improve type safety and error handling
| * | ||
| * Uses local address calculation (no API call needed for prepare step) | ||
| */ | ||
| export async function createEthWalletAccount( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File can be expanded to include passkeys, ED25519 and more for direct/signermode.
Logs to be removed if full implementation is tested conculsively
| * Completes login after redirect callback and returns keypair and granter. | ||
| * Specifically designed for redirect flow to avoid reading from storage (prevents Client/Server inconsistencies). | ||
| * | ||
| * @returns {Promise<{ keypair: SignArbSecp256k1HdWallet; granter: string } | undefined>} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplifies the state management on returning from redirect, localstorage not always directly accesible so returning them solves this issue for SSR frameworks.
I tried verifyoiing that this is 100% secure, afaik it is but some checking wouldnt hurt.
| * Create account via AA API v2 for JWT | ||
| * POST /api/v2/accounts/create/jwt | ||
| */ | ||
| export async function createJWTAccountV2( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not used for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just remove it. JWT will be an internal only thing. If we make it available, we can make another release around it.
| @@ -0,0 +1,59 @@ | |||
| /** | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be nice to just share these types with the account-abstraxion-api if this is possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the entire UI component setup that did:
Abstraxion (hook) --> Modal --> Signing/error/loading.
We now only have the context and the actual hooks to use abstraxion. There is no UI, just clear loading states people can use to show their own.
| useEffect(() => { | ||
| const searchParams = new URLSearchParams(window.location.search); | ||
| const isAuth = searchParams.get("granted") === "true"; | ||
| const unsubscribe = controller.subscribe((newState) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using separate state management now so that we dont have 10s of useEffects handling these states which was very error prone. Works best if people dont use SSR frameworks but also navigates around that.
This also makes the intergation with react-native easier so we dont have to duplicate changes and this managament
| ); | ||
|
|
||
| // Create account strategy | ||
| const accountStrategy = createCompositeAccountStrategy({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a small discussion to be had about how and if we want to expose our indexers for people to use. EarnOs will need them if they want to get the most reliable version of the signer-mode. Else everything will fall back to using RPC through a new method added in account-management.
| feeGranter: config.feeGranter, | ||
| } : undefined; | ||
|
|
||
| // TODO: review this logic or change dashboard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should make a decision here on the expected logic or Alter the dashboard. Especially if latewr we introduce local mode where people might pay for gas themselves somehow.
| "dependencies": { | ||
| "@burnt-labs/abstraxion-core": "workspace:*", | ||
| "@burnt-labs/signers": "workspace:*", | ||
| "@cosmjs/cosmwasm-stargate": "^0.36.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we match cosmjs versions accross all packages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we enforce this via CI somehow?
|
|
||
| const authenticatorIndex = matchingAuthenticator?.authenticatorIndex ?? 0; | ||
|
|
||
| console.log(`${logPrefix} ✅ Found existing account:`, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many logs like these still exist to prove the flow and provide feedback, will be removed once we merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably use a logger package anyway. I'll put a ticket in for that.
| // Use configured codeId (same as AA API and Dashboard) | ||
| return [{ | ||
| id: calculatedAddress, | ||
| codeId: this.config.codeId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couldnt reliably get this from the chain so its now required for Signer-mode.
| authenticatorType = AUTHENTICATOR_TYPE.JWT; | ||
| } else if (authenticatorData.Passkey) { | ||
| authenticatorString = authenticatorData.Passkey.credential_id; | ||
| authenticatorType = AUTHENTICATOR_TYPE.Passkey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much of this is to be tested fully when moving the dashboard to use these utils instead of its own code.
Most of these hooks and strats are 1/1 copies with some better type safety or structure so it should be good but cant be tested until we move over the dashboard.
| return await connectionResult.signMessage(hexMessage); | ||
| }; | ||
|
|
||
| const result = await createEthWalletAccount( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when dashboard moves to this code we can expand this with JWT,passkey and other options or create separate flows.
| includeDirectQuery: true, | ||
| }); | ||
|
|
||
| const threeMonthsFromNow = BigInt( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took this from the dashboard but it seems to me this should be more defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like configurable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, kinda strange we are just making all session keys work for 3 months even if logged out etc.
|
TODO: Extensive test coverage |
|
|
||
| if (grantsExist) { | ||
| // Grants already exist - return success | ||
| return { success: true }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question. Here we are checking if grants exist in storage and then returning true if we find them. Could we run into an issue if grants have changed? Like if grants were added or removed in the developer portal, would this effect the user in anyway besides just showing stale grants?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the creation flow, meaning the grants have literally just run. This is why it skips over validation.
Youll see that on session restoration etc it does run "authenticate" which checks for the grants existing from that granter address and being valid with the treasury contract.
To be clear this only works with the treasury contract configured, not with legacy permissions.
However as mentioned aboce in a comment all grants are valid for 3 weeks. so if permissions are removed alll it can do is logout and force you to make new session keys. which is what it does.
Nonetheless this is a good integration test i should create.
|
@claude can you take a look? |
|
Claude finished @ertemann's task —— View job Code Review ✅I've completed a comprehensive review of this large PR. This is an ambitious architectural refactoring that adds signer mode support alongside the existing redirect flow. Here are my findings: 🏗️ Architectural AssessmentStrengths:
Concerns:
🔒 Security ReviewHigh Priority Issues:1. Session Management Security (packages/abstraxion-core/src/AbstraxionAuth.ts:660) const urlGranter = await this.redirectStrategy.getUrlParameter("granter");
const granter = storedGranter || urlGranter;
2. Grant Expiration Hardcoded (packages/account-management/src/orchestrator/flow/grantCreation.ts:112-116) const threeMonthsFromNow = BigInt(
Math.floor(
new Date(new Date().setMonth(new Date().getMonth() + 3)).getTime() / 1000,
),
);
3. Account Creation Signature Validation // packages/abstraxion-core/src/connectors/ExternalSignerConnector.ts:93-94
return formatEthSignature(signature);✅ Validates signature length and format - good! 4. Error Messages Leaking Info (packages/abstraxion-core/src/api/client.ts:20-38) 🐛 Code Quality IssuesConsole Logs (HIGH - Remove before merge)Found 23 files with console.log/warn/error statements. Examples: Debugging logs to remove:
Review comments already flag some (packages/account-management/src/accounts/discovery.ts), but this is widespread. Recommendation:
Type Safety Issues:1. Type assertions that bypass safety: // packages/abstraxion/src/components/AbstraxionContext/index.tsx:87-95
const accountInfo: AccountInfo = {
keypair: (restorationResult as { restored: true } & AccountInfo).keypair,
granterAddress: (restorationResult as { restored: true } & AccountInfo).granterAddress,
// ...
};This pattern appears in multiple places. Consider using type guards or restructuring types to avoid assertions. 2. Missing error types: // packages/abstraxion-core/src/connectors/ExternalSignerConnector.ts:137
} catch (error: any) {
throw new Error(`Failed to connect to ${this.config.name}: ${error.message || error}`);
}Using 📝 Specific File Reviewspackages/abstraxion/src/controllers/SignerController.tsGood:
Issues:
packages/abstraxion/src/components/AbstraxionContext/index.tsxGood:
Issues:
packages/account-management/src/orchestrator/flow/grantCreation.tsGood:
Issues:
packages/abstraxion-core/src/api/createAccount.tsIssues:
packages/abstraxion/src/utils/controllerFactory.tsIssues:
🔍 Review Comment Follow-upsAddressing your own review comments:
✅ What's Working Well
🚨 Blockers Before Merge
📋 RecommendationsHigh Priority:
Medium Priority:
Low Priority:
🎯 SummaryThis is solid architectural work that will enable important use cases (Turnkey, wallet integrations). The controller pattern and state machine approach are big improvements. However:
I recommend breaking this into smaller PRs and adding comprehensive tests before proceeding. The architecture is sound, but the execution needs more rigor given the security implications. Files reviewed: 20+ core files across abstraxion, abstraxion-core, and account-management packages |
Still a ton of issues, packages not at all ready.
Creation, persistency etc all works for wallets and in the demo app, its now aboyt converting this to the EarnOs turnkey setup and cleaning up the packages and needed utils to make it work.
!!! - This comes from a branch prior to loading states merge so that has to be reimplemented/rebased still