-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9b342af
commit 06aaadf
Showing
9 changed files
with
348 additions
and
139 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// from extension/src/app/store/common/api-clients.ts | ||
import { useMemo } from 'react'; | ||
|
||
import { stacksClient, useCurrentNetworkState } from '@leather.io/query'; | ||
|
||
export function useStacksClient(): ReturnType<typeof stacksClient> { | ||
const network = useCurrentNetworkState(); | ||
|
||
return useMemo(() => { | ||
return stacksClient(network.chain.stacks.url); | ||
}, [network.chain.stacks.url]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './derivation-path-utils'; | ||
export * from './keychain'; | ||
export * from './signer/signer'; | ||
export * from './recurse-accounts'; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// from extension src/app/common/account-restoration/account-restore.ts | ||
import { createCounter, fibonacciGenerator } from '@leather.io/utils'; | ||
|
||
const numOfEmptyAccountsToCheck = 20; | ||
|
||
interface AccountIndexActivityCheckHistory { | ||
index: number; | ||
hasActivity: boolean; | ||
} | ||
|
||
function minNumberOfAccountsNotChecked(num: number) { | ||
return num < numOfEmptyAccountsToCheck; | ||
} | ||
|
||
function anyOfLastCheckedAccountsHaveActivity(arr: AccountIndexActivityCheckHistory[]) { | ||
return arr.slice(arr.length - numOfEmptyAccountsToCheck).some(check => check.hasActivity); | ||
} | ||
|
||
function returnHighestIndex(arr: AccountIndexActivityCheckHistory[]) { | ||
return Math.max(0, ...arr.filter(check => check.hasActivity).map(check => check.index)); | ||
} | ||
|
||
async function recurseUntilGeneratorDone(generator: AsyncGenerator): Promise<any> { | ||
const result = await generator.next(); | ||
if (result.done) return result.value; | ||
return recurseUntilGeneratorDone(generator); | ||
} | ||
|
||
interface RecurseAccountsForActivityArgs { | ||
doesAddressHaveActivityFn(index: number): Promise<boolean>; | ||
} | ||
|
||
/** | ||
* Used to recursively look for account activity. The use case is that, when | ||
* restoring an account, we want to know how many accounts to generate. This | ||
* function makes no assumption as to what constitutes an active account. It | ||
* takes a function that returns a boolean. If true, it means that the account | ||
* at the given index is considered to have activity. | ||
* | ||
* Original PR was https://github.com/leather-io/extension/pull/3026 | ||
*/ | ||
export async function recurseAccountsForActivity({ | ||
doesAddressHaveActivityFn, | ||
}: RecurseAccountsForActivityArgs): Promise<number> { | ||
async function* findHighestAddressIndexExponent() { | ||
const fibonacci = fibonacciGenerator(2); | ||
const activity: AccountIndexActivityCheckHistory[] = []; | ||
|
||
while (activity.length === 0 || activity[activity.length - 1]?.hasActivity) { | ||
const index = fibonacci.next().value; | ||
const hasActivity = await doesAddressHaveActivityFn(index); | ||
activity.push({ index, hasActivity }); | ||
yield; | ||
} | ||
return returnHighestIndex(activity); | ||
} | ||
|
||
const knownActivityAtIndex = await recurseUntilGeneratorDone(findHighestAddressIndexExponent()); | ||
async function* checkForMostRecentAccount() { | ||
const indexCounter = createCounter(knownActivityAtIndex + 1); | ||
const activity: AccountIndexActivityCheckHistory[] = []; | ||
|
||
while ( | ||
minNumberOfAccountsNotChecked(activity.length) || | ||
anyOfLastCheckedAccountsHaveActivity(activity) | ||
) { | ||
const hasActivity = await doesAddressHaveActivityFn(indexCounter.getValue()); | ||
activity.push({ index: indexCounter.getValue(), hasActivity }); | ||
indexCounter.increment(); | ||
yield; | ||
} | ||
return returnHighestIndex(activity); | ||
} | ||
const mostRecentAccount = await recurseUntilGeneratorDone(checkForMostRecentAccount()); | ||
const accountsToRestore = mostRecentAccount; | ||
return accountsToRestore; | ||
} | ||
Oops, something went wrong.