Skip to content

Commit

Permalink
Merge branch 'main' into refactor/auto-gas
Browse files Browse the repository at this point in the history
  • Loading branch information
BurntVal authored Oct 17, 2024
2 parents a3b89b6 + bfdc30e commit c3148e8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/sharp-carpets-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@burnt-labs/abstraxion-core": minor
---

Added a grant validity check to verify expiration
59 changes: 46 additions & 13 deletions packages/abstraxion-core/src/AbstraxionAuth.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { GasPrice } from "@cosmjs/stargate";
import { fetchConfig } from "@burnt-labs/constants";
import type { ContractGrantDescription, SpendLimit } from "@/types";
import type {
ContractGrantDescription,
GrantsResponse,
SpendLimit,
} from "@/types";
import { GranteeSignerClient } from "./GranteeSignerClient";
import { SignArbSecp256k1HdWallet } from "./SignArbSecp256k1HdWallet";

Expand Down Expand Up @@ -312,12 +316,20 @@ export class AbstraxionAuth {
const res = await fetch(url, {
cache: "no-store",
});
const data = await res.json();
if (data.grants.length > 0) {
return true;
const data: GrantsResponse = await res.json();
if (data.grants.length === 0) {
console.warn("No grants found.");
return false;
}
// Retry if no grants found
throw new Error("No grants found.");

// Check expiration for each grant
const currentTime = new Date().toISOString();
const validGrant = data.grants.some((grant) => {
const { expiration } = grant;
return !expiration || expiration > currentTime;
});

return validGrant;
} catch (error) {
console.warn("Error fetching grants: ", error);
const delay = Math.pow(2, retries) * 1000;
Expand All @@ -341,16 +353,37 @@ export class AbstraxionAuth {

/**
* Authenticates the user based on the presence of a local keypair and a granter address.
* If a local keypair and granter address are found, sets the abstract account and triggers authentication state change.
* This method is typically called to authenticate the user and persist state between renders.
* Also checks if the grant is still valid by verifying the expiration.
* If valid, sets the abstract account and triggers authentication state change.
* If expired, clears local state and prompts reauthorization.
*
* @returns {Promise<void>} - Resolves if authentication is successful or logs out the user otherwise.
*/
async authenticate(): Promise<void> {
const keypair = await this.getLocalKeypair();
const granter = this.getGranter();
try {
const keypair = await this.getLocalKeypair();
const granter = this.getGranter();

if (keypair && granter) {
this.abstractAccount = keypair;
this.triggerAuthStateChange(true);
if (!keypair || !granter) {
console.warn("Missing keypair or granter, cannot authenticate.");
return;
}

const accounts = await keypair.getAccounts();
const keypairAddress = accounts[0].address;

// Check for existing grants with an expiration check
const isGrantValid = await this.pollForGrants(keypairAddress, granter);

if (isGrantValid) {
this.abstractAccount = keypair;
this.triggerAuthStateChange(true);
} else {
throw new Error("Grant expired or not found. Logging out.");
}
} catch (error) {
console.error("Error during authentication:", error);
this.logout();
}
}

Expand Down

0 comments on commit c3148e8

Please sign in to comment.