chore: changes for 1.4.11

This commit is contained in:
Andrei O 2025-01-23 10:03:48 +02:00
parent bf8b86849e
commit ff2215b192
No known key found for this signature in database
GPG Key ID: B961E5B68389457E
15 changed files with 168 additions and 64 deletions

View File

@ -1,5 +1,14 @@
# Changelog # Changelog
## Manifest Version 1.4.11
- bumped all dependencies to the latest versions
- changed release script to automatically take the latest version changes from the CHANGELOG.md
- minor UI change to main view of the wallet
- improved account selection UI and UX ( network selection view )
- updated CI script logic and dependencies
- added search in account selection in farcaster action view too
## Manifest Version 1.4.10 ## Manifest Version 1.4.10
- changed release script to automatically take the changes from the CHANGELOG.md - changed release script to automatically take the changes from the CHANGELOG.md

Binary file not shown.

View File

@ -6,6 +6,7 @@ const args = Bun.argv.slice(2);
const secrets = args[0] const secrets = args[0]
const event = args[1] const event = args[1]
const action = args[2] const action = args[2]
const changeLogUrl = 'https://clear-wallet.flashsoft.eu/docs/automated-changelog/'
type TGithubEvent = { type TGithubEvent = {
inputs: { inputs: {
@ -41,9 +42,6 @@ const main = async () => {
const ENABLED = true; const ENABLED = true;
let YUP_PK = ''; let YUP_PK = '';
let FC_SIGNER = '' let FC_SIGNER = ''
let HUB_URL = ''
let HUB_USER = ''
let HUB_PASS = ''
let GithubEvent: TGithubEvent = {} as TGithubEvent; let GithubEvent: TGithubEvent = {} as TGithubEvent;
const USER_FID = 709233; const USER_FID = 709233;
@ -53,16 +51,13 @@ const main = async () => {
const parsedSecrets = JSON.parse(secrets); const parsedSecrets = JSON.parse(secrets);
YUP_PK = parsedSecrets.YUP_PK; YUP_PK = parsedSecrets.YUP_PK;
FC_SIGNER = parsedSecrets.FC_SIGNER; FC_SIGNER = parsedSecrets.FC_SIGNER;
HUB_URL = parsedSecrets.HUB_URL;
HUB_USER = parsedSecrets.HUB_USER;
HUB_PASS = parsedSecrets.HUB_PASS;
GithubEvent = JSON.parse(event); GithubEvent = JSON.parse(event);
} catch (e) { } catch (e) {
console.error('Error parsing data', e) console.error('Error parsing data', e)
} }
const yupAPI = new YupAPI({ PK: YUP_PK }); const yupAPI = new YupAPI({ PK: YUP_PK });
const fchubUtils = new FCHubUtils(FC_SIGNER, USER_FID, HUB_URL, HUB_USER, HUB_PASS); const fchubUtils = new FCHubUtils(FC_SIGNER, USER_FID);
if (action === 'update') { if (action === 'update') {
const VERSION = GithubEvent.inputs.version; const VERSION = GithubEvent.inputs.version;
@ -84,7 +79,7 @@ const main = async () => {
const fcPostHash = Buffer.from(fcPost).toString('hex'); const fcPostHash = Buffer.from(fcPost).toString('hex');
if (fcPostHash) { if (fcPostHash) {
await new Promise((resolve) => setTimeout(resolve, 3000)); await new Promise((resolve) => setTimeout(resolve, 3000));
const launchCasterMessage = `@launch` const launchCasterMessage = `@launch New Clear Wallet version ${VERSION} released! \n\nChanges: ${changeLogUrl}`
await fchubUtils.createFarcasterPost({ await fchubUtils.createFarcasterPost({
content: launchCasterMessage, replyTo: { content: launchCasterMessage, replyTo: {

View File

@ -3,13 +3,13 @@
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {
"@types/bun": "latest" "@types/bun": "^1.1.18"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^5.5.3" "typescript": "^5.7.3"
}, },
"dependencies": { "dependencies": {
"farcaster-hub-utils": "0.1.8", "farcaster-hub-utils": "0.1.10",
"yup-api-interact": "0.1.7" "yup-api-interact": "0.1.7"
}, },
"license": "MIT" "license": "MIT"

BIN
bun.lockb

Binary file not shown.

View File

@ -27,7 +27,7 @@
"vue-router": "^4.5.0" "vue-router": "^4.5.0"
}, },
"devDependencies": { "devDependencies": {
"@crxjs/vite-plugin": "2.0.0-beta.28", "@crxjs/vite-plugin": "2.0.0-beta.30",
"@types/archiver": "^6.0.3", "@types/archiver": "^6.0.3",
"@types/chrome": "^0.0.297", "@types/chrome": "^0.0.297",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",

View File

@ -27,33 +27,28 @@ function limitedSplit(str: string, delimiter: string, limit: number): string[] {
if (limit <= 0) { if (limit <= 0) {
throw new Error("Limit must be greater than 0"); throw new Error("Limit must be greater than 0");
} }
const result: string[] = []; const result: string[] = [];
let current = 0; let remaining: string = str;
let found; for (let i = 0; i < limit; i++) {
const index = remaining.indexOf(delimiter);
do { if (index === -1) {
found = str.indexOf(delimiter, current);
if (found === -1 || result.length === limit - 1) {
result.push(str.substring(current));
break; break;
} }
result.push(str.substring(current, found)); result.push(remaining.substring(0, index));
current = found + delimiter.length; remaining = remaining.substring(index + delimiter.length);
} while (true); }
return result; return result;
} }
const getLastChangeLog = async () => { export const getLastChangeLog = async () => {
const mainChainLogPath = 'CHANGELOG.md'; const mainChainLogPath = 'CHANGELOG.md';
const fs = (await pFs).default const fs = (await pFs).default
if (!fs.existsSync(mainChainLogPath)) { if (!fs.existsSync(mainChainLogPath)) {
return ''; return '';
} }
const mainChainLog = await readFirst2000Characters(mainChainLogPath) const mainChainLog = await readFirst2000Characters(mainChainLogPath)
const manifestVersions = limitedSplit(mainChainLog, '## ', 2)[1] const manifestVersions = limitedSplit(mainChainLog, '##', 2)[1]
const changesText = '## ' + manifestVersions const changesText = '##' + manifestVersions
return changesText return changesText
} }
@ -92,10 +87,11 @@ async function ghRelease (isRebuild: boolean) {
if (!isRebuild) { if (!isRebuild) {
const changeLogPath = `releases/${pkg.version}.changelog.md`; const changeLogPath = `releases/${pkg.version}.changelog.md`;
const releaseCreationDate = new Date().toISOString();
fs.writeFileSync( fs.writeFileSync(
changeLogPath, changeLogPath,
`# ${pkg.version} \n `# Latest changes - (${releaseCreationDate})\n\n
${await getLastChangeLog()}`, ${await getLastChangeLog()}`,
); );
const cps = (await pCps) const cps = (await pCps)

View File

@ -0,0 +1,16 @@
import { expect, test } from "bun:test";
import { getLastChangeLog } from '../create-release';
let testOrSkip: typeof test | typeof test.skip;
const testEnabled = {
"getLastLog": true,
}
testOrSkip = testEnabled.getLastLog ? test : test.skip;
testOrSkip("getLastChangeLog", async () => {
const lastChangeLog = await getLastChangeLog();
expect(lastChangeLog.length).toBeGreaterThan(0);
});

View File

@ -3,6 +3,13 @@ import { readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path'; import { resolve } from 'path';
async function main() { async function main() {
// 0. Check tag is not already created
const tags = execSync(`git tag --list`).toString();
if (tags.includes(`v${process.env.npm_package_version}`)) {
console.log(`Tag v${process.env.npm_package_version} already exists`);
return;
}
// 1. Bump version in package.json // 1. Bump version in package.json
const packageJsonPath = resolve('./package.json'); const packageJsonPath = resolve('./package.json');
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));

View File

@ -3,8 +3,8 @@
"name": "__MSG_appName__", "name": "__MSG_appName__",
"description": "__MSG_appDesc__", "description": "__MSG_appDesc__",
"default_locale": "en", "default_locale": "en",
"version": "1.4.10", "version": "1.4.11",
"version_name": "1.4.10", "version_name": "1.4.11",
"icons": { "icons": {
"16": "assets/extension-icon/wallet_16.png", "16": "assets/extension-icon/wallet_16.png",
"32": "assets/extension-icon/wallet_32.png", "32": "assets/extension-icon/wallet_32.png",

View File

@ -612,7 +612,7 @@ const mainListner = (message: RequestArguments, sender: any, sendResponse: (a: a
}, 6e4) }, 6e4)
} }
chrome.notifications.create(notificationId, { chrome.notifications.create(notificationId, {
message: 'Transaction Confirmed', message: 'Transaction Sent',
title: 'Success', title: 'Success',
iconUrl: getUrl('assets/extension-icon/wallet_128.png'), iconUrl: getUrl('assets/extension-icon/wallet_128.png'),
type: 'basic', type: 'basic',

View File

@ -33,7 +33,8 @@
</ion-item> </ion-item>
<ion-item @click="copyText(account.address, getToastRef())"> <ion-item @click="copyText(account.address, getToastRef())">
<p style="font-size: 0.7rem">{{ account.address }}</p> <p style="font-size: 0.7rem">{{ account.address }}</p>
<ion-icon :icon="copyOutline"></ion-icon> &nbsp;
<ion-icon class="copy-icon" :icon="copyOutline"></ion-icon>
</ion-item> </ion-item>
<ion-item> <ion-item>
<ion-chip @click="viewPk(account.address)">View Pk</ion-chip> <ion-chip @click="viewPk(account.address)">View Pk</ion-chip>
@ -233,3 +234,18 @@ export default defineComponent({
}, },
}); });
</script> </script>
<style scoped>
.copy-icon {
font-size: 1.5rem;
color: var(--primary-color);
margin-left: 0.5rem;
}
.copy-icon:hover {
opacity: 0.8;
transition: opacity 0.2s ease-in-out;
transform: scale(1.05);
}
</style>

View File

@ -81,35 +81,57 @@
<ion-buttons slot="start"> <ion-buttons slot="start">
<ion-button @click="accountsModal = false">Close</ion-button> <ion-button @click="accountsModal = false">Close</ion-button>
</ion-buttons> </ion-buttons>
<ion-title>Select</ion-title> <ion-title>Select Account</ion-title>
</ion-toolbar> </ion-toolbar>
</ion-header> </ion-header>
<ion-content class="ion-padding"> <ion-content class="ion-padding">
<ion-list style="margin-bottom: 4rem"> <ion-list style="margin-bottom: 4rem">
<ion-radio-group :value="selectedAccount?.address ?? ''"> <ion-radio-group :value="selectedAccount?.address ?? ''">
<ion-list-header> <ion-list-header>
<ion-label>Accounts</ion-label> <ion-searchbar
placeholder="search..."
autocomplete="off"
autocorrect="off"
:autofocus="true"
:clear-input="false"
:clear-on-edit="false"
:spellcheck="false"
:tabindex="0"
@ionInput="searchAccount"
></ion-searchbar>
</ion-list-header> </ion-list-header>
<ion-list <ion-list
@click="changeSelectedAccount(account.address)" @click="changeSelectedAccount(account.address)"
class="ion-padding" class="ion-padding"
v-for="account of accounts" v-for="account of filtredAccounts"
:key="account.address" :key="account.address"
button button
> >
<ion-item> <ion-item>
<ion-radio <ion-radio
:aria-label="account.name" :aria-label="account.name"
slot="start"
:value="account.address" :value="account.address"
>{{ account.name }}</ion-radio slot="end"
labelPlacement="end"
mode="ios"
justify="start"
color="warning"
style="margin-left: 0.1rem"
> >
</ion-item> <div style="margin-left: 0.5rem">{{ account.name }}</div>
<ion-item> <div style="margin-top: 0.1rem">
<ion-text style="font-size: 0.7rem; color: coral">{{ <ion-text style="font-size: 0.65rem; color: coral">{{
account.address account.address.slice(0, 6)
}}</ion-text> }}</ion-text>
<ion-text style="font-size: 0.65rem">{{
account.address.slice(6, -4)
}}</ion-text>
<ion-text style="font-size: 0.65rem; color: coral">{{
account.address.slice(-4)
}}</ion-text>
</div>
</ion-radio>
</ion-item> </ion-item>
</ion-list> </ion-list>
</ion-radio-group> </ion-radio-group>
@ -279,6 +301,7 @@ export default defineComponent({
const loading = ref(false); const loading = ref(false);
const accounts = ref([]) as Ref<Account[]>; const accounts = ref([]) as Ref<Account[]>;
const filtredAccounts = ref([]) as Ref<Account[]>;
const accountsModal = ref(false) as Ref<boolean>; const accountsModal = ref(false) as Ref<boolean>;
const selectedAccount = (ref(null) as unknown) as Ref<Account>; const selectedAccount = (ref(null) as unknown) as Ref<Account>;
const toastState = ref(false); const toastState = ref(false);
@ -289,6 +312,7 @@ export default defineComponent({
const pSelectedAccount = getSelectedAccount(); const pSelectedAccount = getSelectedAccount();
Promise.all([pAccounts, pSelectedAccount]).then((res) => { Promise.all([pAccounts, pSelectedAccount]).then((res) => {
accounts.value = res[0]; accounts.value = res[0];
filtredAccounts.value = res[0];
selectedAccount.value = res[1]; selectedAccount.value = res[1];
loading.value = false; loading.value = false;
}); });
@ -543,6 +567,19 @@ export default defineComponent({
return false; return false;
}; };
const searchAccount = (e: any) => {
const text = e.target.value;
if (text) {
filtredAccounts.value = accounts.value.filter(
(item) =>
item.name.toLowerCase().includes(text.toLowerCase()) ||
item.address.toLowerCase().includes(text.toLowerCase())
);
} else {
filtredAccounts.value = accounts.value;
}
};
return { return {
name, name,
pk, pk,
@ -567,6 +604,8 @@ export default defineComponent({
exitWallet, exitWallet,
alertHeader, alertHeader,
farcasterSWIWQRAuthorize, farcasterSWIWQRAuthorize,
searchAccount,
filtredAccounts,
}; };
}, },
}); });

View File

@ -8,18 +8,22 @@
> >
<img alt="clw" :src="getUrl('assets/extension-icon/wallet_32.png')" /> <img alt="clw" :src="getUrl('assets/extension-icon/wallet_32.png')" />
</ion-avatar> </ion-avatar>
<span style="position: absolute; top: 0.45rem; margin-left: 0.3rem" <span style="position: absolute; top: 0.35rem; margin-left: 0.3rem">
>CL Wallet</span <span style="font-size: 0.9rem; font-weight: bold; color: #aca3bb">
> Clear
</span>
<span style="font-size: 0.9rem; color: #aca3bb"> Wallet </span>
</span>
<span <span
v-if="version" v-if="version"
style=" style="
position: absolute; position: absolute;
right: 1.1rem; right: 1.1rem;
margin-left: 0.3rem; margin-left: 0.3rem;
color: #645285; color: #aca3bb;
font-weight: bold; font-weight: bold;
font-size: 0.65rem; font-size: 0.65rem;
top: -1px;
" "
>Version: {{ version }}</span >Version: {{ version }}</span
> >
@ -38,7 +42,13 @@
</ion-item> </ion-item>
<ion-list v-else> <ion-list v-else>
<ion-item> <ion-item>
<ion-label>Selected Account: {{ selectedAccount?.name }}</ion-label> <ion-label>
<span style="color: #aca3bb; font-weight: bold; font-size: 0.85rem"
>[ Selected Account ]:</span
>&nbsp;
{{ selectedAccount?.name }}</ion-label
>
<ion-button <ion-button
@click=" @click="
() => { () => {
@ -60,7 +70,7 @@
) )
" "
> >
<p style="font-size: 0.7rem; color: #645285">{{ selectedAccount?.address }}</p> <p style="font-size: 0.7rem; color: #aca3bb">{{ selectedAccount?.address }}</p>
<ion-icon style="margin-left: 0.5rem" :icon="copyOutline"></ion-icon> <ion-icon style="margin-left: 0.5rem" :icon="copyOutline"></ion-icon>
</ion-item> </ion-item>
<ion-item <ion-item
@ -106,10 +116,12 @@
button button
@click="copyText(String(selectedNetwork?.chainId), getToastRef())" @click="copyText(String(selectedNetwork?.chainId), getToastRef())"
style="cursor: pointer" style="cursor: pointer"
>Selected Network ID:&nbsp; >
<span style="color: #645285; font-weight: bold">{{ <span style="color: #aca3bb; font-weight: bold; font-size: 0.85rem"
selectedNetwork?.chainId >[ Selected Network ID ]:</span
}}</span> >
&nbsp;
<span style="font-weight: bold">{{ selectedNetwork?.chainId }}</span>
<ion-icon <ion-icon
style="margin-left: 0.5rem; top: 2px; position: relative" style="margin-left: 0.5rem; top: 2px; position: relative"
:icon="copyOutline" :icon="copyOutline"
@ -181,14 +193,13 @@
<ion-buttons slot="start"> <ion-buttons slot="start">
<ion-button @click="accountsModal = false">Close</ion-button> <ion-button @click="accountsModal = false">Close</ion-button>
</ion-buttons> </ion-buttons>
<ion-title>Select</ion-title> <ion-title>Select Account</ion-title>
</ion-toolbar> </ion-toolbar>
</ion-header> </ion-header>
<ion-content class="ion-padding"> <ion-content class="ion-padding">
<ion-list style="margin-bottom: 4rem"> <ion-list style="margin-bottom: 4rem">
<ion-radio-group :value="selectedAccount?.address ?? ''"> <ion-radio-group :value="selectedAccount?.address ?? ''">
<ion-list-header> <ion-list-header>
<ion-label>Accounts</ion-label>
<ion-searchbar <ion-searchbar
placeholder="search..." placeholder="search..."
autocomplete="off" autocomplete="off"
@ -212,15 +223,27 @@
<ion-item> <ion-item>
<ion-radio <ion-radio
:aria-label="account.name" :aria-label="account.name"
slot="start"
:value="account.address" :value="account.address"
>{{ account.name }}</ion-radio slot="end"
labelPlacement="end"
mode="ios"
justify="start"
color="warning"
style="margin-left: 0.1rem"
> >
</ion-item> <div style="margin-left: 0.5rem">{{ account.name }}</div>
<ion-item> <div style="margin-top: 0.1rem">
<ion-text style="font-size: 0.7rem; color: coral">{{ <ion-text style="font-size: 0.65rem; color: coral">{{
account.address account.address.slice(0, 6)
}}</ion-text> }}</ion-text>
<ion-text style="font-size: 0.65rem">{{
account.address.slice(6, -4)
}}</ion-text>
<ion-text style="font-size: 0.65rem; color: coral">{{
account.address.slice(-4)
}}</ion-text>
</div>
</ion-radio>
</ion-item> </ion-item>
</ion-list> </ion-list>
</ion-radio-group> </ion-radio-group>
@ -261,12 +284,14 @@
<ion-item> <ion-item>
<ion-radio <ion-radio
@click="changeSelectedNetwork(network.chainId)" @click="changeSelectedNetwork(network.chainId)"
slot="start"
:value="network.chainId" :value="network.chainId"
:aria-label="network.name" :aria-label="network.name"
slot="start"
labelPlacement="start" labelPlacement="start"
mode="ios" mode="ios"
justify="space-between" justify="space-between"
color="warning"
style="padding: 0.5rem"
> >
<div> <div>
<ion-avatar <ion-avatar
@ -571,7 +596,7 @@ export default defineComponent({
top: 0.9rem; top: 0.9rem;
right: 2.4rem; right: 2.4rem;
margin-left: 0.3rem; margin-left: 0.3rem;
color: #645285; color: #aca3bb;
font-weight: bold; font-weight: bold;
font-size: 0.65rem; font-size: 0.65rem;
cursor: pointer; cursor: pointer;

View File

@ -36,6 +36,7 @@
"tests/**/*.tsx" "tests/**/*.tsx"
], ],
"exclude": [ "exclude": [
"node_modules" "node_modules",
"dist"
] ]
} }