Skip to content
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

feat: kadena provider changes #371

Merged
merged 75 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
cc36bb4
Chnage Kadena derivation path to account
andborges Oct 31, 2023
666ae8b
update send transaction page to show the right KDA currency name
Peixer Nov 9, 2023
ad4d71f
Merge branch 'feature/kadena-provider' into feature/account-derivatio…
Peixer Nov 15, 2023
c5cedbf
WIP - Add multi-chain
Peixer Nov 20, 2023
3b7a08e
WIP - Update multi-chain
Peixer Nov 20, 2023
c036d88
update network-activity component to watch selectedChainId
Peixer Nov 20, 2023
5bedfc6
small refactor and update in App.vue to init the right chainId state
Peixer Nov 20, 2023
49af352
small refactor at kadena api
Peixer Nov 21, 2023
f255b33
Add chain provider
mateus-batista Nov 21, 2023
60ea6ca
remove chainProvider
Peixer Nov 22, 2023
2a6b843
refactor in App and header-accounts
Peixer Nov 22, 2023
da38a0e
update kadena account state
Peixer Nov 22, 2023
6690eb2
refactor kadena defaultChainId
Peixer Nov 22, 2023
ca7c534
update header-account component
Peixer Nov 22, 2023
510b302
small refactor regarding chainId
Peixer Nov 22, 2023
89dc379
fix avatar icons
Peixer Nov 22, 2023
88c7d98
update kadena derivation path to follow Kadena standard
Peixer Nov 22, 2023
fece4ea
update Kadena chain-list component
Peixer Nov 23, 2023
39f4a55
small refactor at network components
Peixer Nov 23, 2023
7ae1aa0
small css changes
Peixer Nov 23, 2023
9d02e40
update kda_getBalance
Peixer Nov 23, 2023
4edfb52
update sign test
Peixer Nov 24, 2023
642349e
fix kadena unit tests
Peixer Nov 24, 2023
9cdfc47
update send transaction validation of Kadena
Peixer Nov 28, 2023
bf54227
add custom buy link for Kadena testnet
Peixer Nov 28, 2023
481fe12
update deposit component to show chain id selected
Peixer Nov 28, 2023
7ba7aa6
Update display amount as negative in network-activity-transaction com…
Peixer Nov 28, 2023
f6c0f04
remove debugger lost in code
Peixer Nov 29, 2023
c0688da
add negative signal in network-transaction for Kadena network
Peixer Nov 29, 2023
37793a6
update send-address-input component to emit any input change
Peixer Nov 29, 2023
8225d83
added transaction result validation, it should be success to allow th…
Peixer Dec 5, 2023
bf29d26
Merge pull request #1 from agencyenterprise/feature/multi-chain
Peixer Dec 5, 2023
efb0ee6
update keyring tests
Peixer Dec 5, 2023
059acc2
Merge pull request #370 from kadena-community/feature/kadena-provider
kvhnuke Dec 14, 2023
47fd278
devop: create subnetworks
kvhnuke Dec 14, 2023
a9abd3c
devop: remove conditional kadena statements
kvhnuke Dec 14, 2023
4eb9143
Change kadena subnetworks to 20 for mainnet and testnet
Takadenoshi Jan 16, 2024
25b3a41
Update kadena testnet faucet link
Takadenoshi Jan 16, 2024
fe35ba5
Update kadena logomark to new branding
Takadenoshi Jan 18, 2024
6685d2d
Merge pull request #382 from Takadenoshi/fix/update-kadena-logo
kvhnuke Jan 18, 2024
009cdfb
Merge pull request #380 from Takadenoshi/fix/kadena-subchain-data
kvhnuke Jan 18, 2024
3824b99
Change balance lookup to use @kadena/client instead of pact-lang-api.…
Takadenoshi Jan 18, 2024
5a56203
replace pact-lang-api in getTransactionStatus; remove pect-lang-api
Takadenoshi Jan 18, 2024
4c1516f
simplify getTransactionStatus
Takadenoshi Jan 22, 2024
9ff4f2f
Merge pull request #385 from Takadenoshi/fix/remove-pact-lang-api
kvhnuke Jan 23, 2024
a6ea1be
Kadena: add chain ID to activity transaction entries
Takadenoshi Jan 29, 2024
fb1a506
broken
Takadenoshi Jan 29, 2024
74e5870
Kadena: add chain ID to activity transaction entries
Takadenoshi Jan 29, 2024
f09edd0
Kadena: fix missing sender/receiver for cross chain transfers in acti…
Takadenoshi Jan 29, 2024
20339ea
Kadena: activity transaction entries: change on/from based on isIncom…
Takadenoshi Jan 30, 2024
26e0e66
kadena: reorder v-if / class
Takadenoshi Jan 30, 2024
29727bd
Refactor account retrieval logic in kda_requestAccounts.handleRemaini…
andborges Jan 30, 2024
3c3a143
Update router navigation in sendAction function
andborges Jan 30, 2024
1b1335a
Updating assets when subnetwork changes
andborges Jan 31, 2024
92fae22
Update input validation class in send-input-amount
andborges Jan 31, 2024
74c08c5
Add balance update functionality when activities are updated
andborges Feb 1, 2024
08acb73
Updating assets when subnetwork changes
andborges Jan 31, 2024
6519f45
fix data propagation, simplify
Takadenoshi Feb 1, 2024
5b7ce11
linting
Takadenoshi Feb 1, 2024
72e9efa
fix props in network-activity
Takadenoshi Feb 1, 2024
40fae34
Fixed Kadena type in Activity.rawInfo
Takadenoshi Feb 5, 2024
dc7a1cb
change some kadena-specific code
Takadenoshi Feb 5, 2024
e8f3778
simplify more
Takadenoshi Feb 5, 2024
07319fe
revert symbol->network change in network-activity-total
Takadenoshi Feb 5, 2024
64d315a
Add send-alert component to send-transaction and verify-transaction
andborges Feb 6, 2024
046886a
Linting issues
andborges Feb 6, 2024
1b04bfe
Merge pull request #1 from agencyenterprise/bugfix/outstanding-issues
andborges Feb 6, 2024
52d8a88
Refactor sendAction function and remove unused CSS styles
andborges Feb 6, 2024
6df418e
Merge pull request #388 from Takadenoshi/fix/activities-kadena-add-cr…
kvhnuke Feb 6, 2024
e584cad
Merge pull request #387 from Takadenoshi/feat/kadena-chain-label-in-a…
kvhnuke Feb 6, 2024
86fe870
Merge pull request #389 from Takadenoshi/feat/kadena-chain-label-in-a…
kvhnuke Feb 6, 2024
e0e89da
Merge pull request #392 from agencyenterprise/feat/kadena-provider-2
kvhnuke Feb 22, 2024
786d51d
devop: merge main
kvhnuke Feb 22, 2024
5a648b3
devop: merge with upstream
kvhnuke Feb 22, 2024
0a90c04
devop: minor changes
kvhnuke Feb 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
"private": true,
"scripts": {
"zip": "cd dist; zip -r release.zip *;",
"build:chrome": "cross-env BROWSER='chrome' vue-cli-service build && yarn build:rollup",
"build:firefox": "cross-env BROWSER='firefox' vue-cli-service build && yarn build:rollup && node configs/get-system-info.js",
"prebuild": "yarn kadena:prebuild",
"build:chrome": "yarn prebuild && cross-env BROWSER='chrome' vue-cli-service build && yarn build:rollup",
"build:firefox": "yarn prebuild && cross-env BROWSER='firefox' vue-cli-service build && yarn build:rollup && node configs/get-system-info.js",
"lint": "vue-cli-service lint --fix",
"build:rollup": "cross-env minify=on rollup --config configs/rollup.config.contentscript.mjs && cross-env minify=on rollup --config configs/rollup.config.inject.mjs",
"inspectWebpack": "vue-cli-service inspect > webpack.log",
"kadena:prebuild": "pactjs contract-generate --contract=coin --api https://api.chainweb.com/chainweb/0.0/mainnet01/chain/1/pact",
"test": "ts-mocha --require ./configs/testNullCompiler.js --paths -p configs/tsconfig.test.json ./**/*.mocha.ts",
"watch": "rimraf dist && concurrently 'npm:watch-*(!firefox)'",
"watch:firefox": "concurrently 'npm:watch-*(!chrome)'",
"watch": "yarn prebuild && rimraf dist && concurrently 'npm:watch-*(!firefox)'",
"watch:firefox": "yarn prebuild && concurrently 'npm:watch-*(!chrome)'",
"watch-contentscript": "rollup --watch --config configs/rollup.config.contentscript.mjs",
"watch-inject": "rollup --watch --config configs/rollup.config.inject.mjs",
"watch-vue-chrome": "cross-env BROWSER='chrome' vue-cli-service build --watch --no-clean",
Expand Down Expand Up @@ -74,6 +76,7 @@
},
"devDependencies": {
"@babel/plugin-transform-class-static-block": "^7.23.4",
"@kadena/pactjs-cli": "^1.7.0",
"@polkadot/api": "^10.11.2",
"@polkadot/extension-inject": "^0.46.6",
"@polkadot/keyring": "^12.6.2",
Expand Down
10 changes: 10 additions & 0 deletions packages/extension/src/libs/domain-state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ class DomainState {
if (state.selectedNetwork) return state.selectedNetwork;
return null;
}
async setSelectedSubNetwork(id: string): Promise<void> {
const state = await this.getState();
state.selectedSubNetworkId = id;
await this.setState(state);
}
async getSelectedSubNetWork(): Promise<string | null> {
const state = await this.getState();
if (state.selectedSubNetworkId) return state.selectedSubNetworkId;
return null;
}
async setSelectedAddress(address: string): Promise<void> {
const state = await this.getState();
state.selectedAddress = address;
Expand Down
1 change: 1 addition & 0 deletions packages/extension/src/libs/domain-state/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export enum StorageKeys {
}
export interface IState {
selectedNetwork?: string;
selectedSubNetworkId?: string;
selectedAddress?: string;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { InternalStorageNamespace } from "@/types/provider";
import BrowserStorage from "@/libs/common/browser-storage";
import { IState, StorageKeys } from "./types";

class AccountState {
#storage: BrowserStorage;
constructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const getAddressActivity = async (
height: number
): Promise<any[]> => {
const url = `${endpoint}txs/account/${address}?minheight=${height}&limit=200&token=coin`;

return cacheFetch({ url }, ttl)
.then((res) => {
return res ? res : [];
Expand Down Expand Up @@ -72,13 +71,25 @@ export default async (
: "0",
network.decimals
);
// note: intentionally not using fromAccount === some-value
// I want to match both null and "" in fromAccount/toAccount
// actual values will be a (truthy) string
let { fromAccount, toAccount } = activity;
if (!fromAccount && activity.crossChainAccount) {
fromAccount = activity.crossChainAccount;
}
if (!toAccount && activity.crossChainAccount) {
toAccount = activity.crossChainAccount;
}
return {
nonce: i.toString(),
from: activity.fromAccount,
to: activity.toAccount,
from: fromAccount,
to: toAccount,
isIncoming: activity.fromAccount !== address,
network: network.name,
rawInfo: activity,
chainId: activity.chain.toString(),
crossChainId: activity.crossChainId,
status:
activity.idx === 1 ? ActivityStatus.success : ActivityStatus.failed,
timestamp: new Date(activity.blockTime).getTime(),
Expand Down
96 changes: 63 additions & 33 deletions packages/extension/src/providers/kadena/libs/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ import { ProviderAPIInterface } from "@/types/provider";
import { KadenaNetworkOptions } from "../types/kadena-network";
import {
ICommand,
IUnsignedCommand,
ICommandResult,
ITransactionDescriptor,
createClient,
Pact,
ChainId,
} from "@kadena/client";
import { toBase } from "@enkryptcom/utils";
import DomainState from "@/libs/domain-state";

class API implements ProviderAPIInterface {
decimals: number;
node: string;
networkId: string;
chainId: string;
apiHost: string;
domainState: DomainState;
displayAddress: (address: string) => string;

constructor(node: string, options: KadenaNetworkOptions) {
Expand All @@ -24,29 +29,53 @@ class API implements ProviderAPIInterface {
this.chainId = options.kadenaApiOptions.chainId;
this.apiHost = `${node}/${this.networkId}/chain/${this.chainId}/pact`;
this.displayAddress = options.displayAddress;
this.domainState = new DomainState();
}

public get api() {
return this;
}

private getApiHost(chainId: string) {
return `${this.node}/${this.networkId}/chain/${chainId}/pact`;
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
async init(): Promise<void> {}

async getTransactionStatus(hash: string): Promise<KadenaRawInfo | null> {
const Pact = require("pact-lang-api");

const cmd = { requestKeys: [hash] };
const transactions = await Pact.fetch.poll(cmd, this.apiHost);
async getChainId(): Promise<string> {
return this.domainState.getSelectedSubNetWork().then((id) => {
if (id) return id;
return "0";
});
}

return transactions[hash];
async getTransactionStatus(requestKey: string): Promise<KadenaRawInfo> {
const chainId = await this.getChainId();
const networkId = this.networkId;
const { pollStatus } = createClient(this.getApiHost(chainId));
const responses = await pollStatus({
requestKey,
networkId,
chainId: chainId as ChainId,
});
return responses[requestKey];
}

async getBalance(address: string): Promise<string> {
const balance = await this.getBalanceAPI(this.displayAddress(address));
async getBalanceByChainId(address: string, chainId: string): Promise<string> {
const balance = await this.getBalanceAPI(
this.displayAddress(address),
chainId
);

if (balance.result.error) {
return toBase("0", this.decimals);
if (balance.result.status === "failure") {
const error = balance.result.error as { message: string | undefined };
const message = error.message ?? "Unknown error retrieving balances";
// expected error when account does not exist on a chain (balance == 0)
if (message.includes("row not found")) {
return toBase("0", this.decimals);
}
throw new Error(message);
}

const balanceValue = parseFloat(balance.result.data.toString()).toFixed(
Expand All @@ -56,49 +85,50 @@ class API implements ProviderAPIInterface {
return toBase(balanceValue, this.decimals);
}

async getBalanceAPI(account: string) {
const Pact = require("pact-lang-api");

const cmd = {
networkId: this.networkId,
pactCode: `(coin.get-balance "${account}")`,
envData: {},
meta: {
creationTime: Math.round(new Date().getTime() / 1000),
ttl: 600,
gasLimit: 600,
chainId: this.chainId,
gasPrice: 0.0000001,
sender: "",
},
};

return Pact.fetch.local(cmd, this.apiHost);
async getBalance(address: string): Promise<string> {
const chainId = await this.getChainId();
return this.getBalanceByChainId(address, chainId);
}

async getBalanceAPI(account: string, chainId: string) {
const transaction = Pact.builder
.execution(Pact.modules.coin["get-balance"](account))
.setMeta({ chainId: chainId as ChainId })
.setNetworkId(this.networkId)
.createTransaction();

return this.dirtyRead(transaction);
}

async sendLocalTransaction(
signedTranscation: ICommand
): Promise<ICommandResult> {
const client = createClient(this.apiHost);
const chainId = await this.getChainId();
const client = createClient(this.getApiHost(chainId));
return client.local(signedTranscation as ICommand);
}

async sendTransaction(
signedTranscation: ICommand
): Promise<ITransactionDescriptor> {
const client = createClient(this.apiHost);
const chainId = await this.getChainId();
const client = createClient(this.getApiHost(chainId));
return client.submit(signedTranscation as ICommand);
}

async listen(
transactionDescriptor: ITransactionDescriptor
): Promise<ICommandResult> {
const client = createClient(this.apiHost);
const chainId = await this.getChainId();
const client = createClient(this.getApiHost(chainId));
return client.listen(transactionDescriptor);
}

async dirtyRead(signedTranscation: ICommand): Promise<ICommandResult> {
const client = createClient(this.apiHost);
async dirtyRead(
signedTranscation: ICommand | IUnsignedCommand
): Promise<ICommandResult> {
const chainId = await this.getChainId();
const client = createClient(this.getApiHost(chainId));
return client.dirtyRead(signedTranscation);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MiddlewareFunction } from "@enkryptcom/types";
import KadenaProvider from "..";
import { ProviderRPCRequest } from "@/types/provider";
import { getCustomError } from "@/libs/error";
import type KadenaAPI from "@/providers/kadena/libs/api";

const method: MiddlewareFunction = function (
this: KadenaProvider,
Expand All @@ -11,12 +12,15 @@ const method: MiddlewareFunction = function (
): void {
if (payload.method !== "kda_getBalance") return next();
else {
if (!payload.params || payload.params.length < 1) {
if (!payload.params || payload.params.length < 2) {
return res(getCustomError("kda_getBalance: invalid params"));
}

const address = payload.params[0];
const chainId =
payload.params[1] ?? this.network.options.kadenaApiOptions.chainId;
this.network.api().then((api) => {
api.getBalance(payload.params![0]).then((bal) => {
(api as KadenaAPI).getBalanceByChainId(address, chainId).then((bal) => {
res(null, bal);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,28 +97,46 @@ const method: MiddlewareFunction = function (
isAccountAccessPending = true;
const accountsState = new AccountState();

accountsState.isApproved(_payload.options.domain).then((isApproved) => {
if (isApproved) {
getAccounts().then((acc) => {
_res(null, acc);
handleRemainingPromises();
});
} else {
const windowPromise = new WindowPromise();
windowPromise
.getResponse(
this.getUIPath(this.UIRoutes.kdaAccounts.path),
JSON.stringify(payload)
)
.then(({ error }) => {
if (error) res(error);
else getAccounts().then((acc) => res(null, acc));
})
.finally(handleRemainingPromises);
}
});
accountsState
.isApproved(_payload.options.domain)
.then((isApproved) => {
if (isApproved) {
getAccounts()
.then((acc) => {
_res(null, acc);
})
.catch((err) => {
throw err;
});
} else {
const windowPromise = new WindowPromise();
windowPromise
.getResponse(
this.getUIPath(this.UIRoutes.kdaAccounts.path),
JSON.stringify(payload)
)
.then(({ error }) => {
if (error) {
throw error;
} else {
getAccounts()
.then((acc) => {
_res(null, acc);
})
.catch((err) => {
throw err;
});
}
});
}
})
.catch((err) => {
_res(err);
})
.finally(handleRemainingPromises);
} else {
_res(getCustomError("No domain set!"));
handleRemainingPromises();
}
};

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ const kadenaOptions: KadenaNetworkOptions = {
networkId: "testnet04",
chainId: "1",
},
subNetworks: Array(20)
.fill("")
.map((_, idx) => {
return {
id: idx.toString(),
name: `Chain ${idx}`,
};
}),
buyLink: "https://tools.kadena.io/faucet/new",
activityHandler: wrapActivityHandler(kadenaScanActivity),
displayAddress: (address: string) => address.replace("0x", "k:"),
isAddress: isValidAddress,
Expand Down
Loading
Loading