Skip to content

Commit

Permalink
feat/140 - Multi-chain configurations (anoma#153)
Browse files Browse the repository at this point in the history
* Adding chain config types, and several default chain configs

* Minor adjustments to config

* Hook namada-interface up to new chains config and type

* Update integrations to incorporate new chain config

* Add common interface for integrations

* Continue refactoring for new configs, removing old config

* clean up, remove old IBC config, correctly pull chain config

* Update extension to utlize shared config properly

* Finish extension config, continue integration with namada-interface

* Fix initialization of Anoma extension in context

* Add ability to override chain configs via .env

* Map Keplr accounts to our Account type to support state

* Minor clean-up

* Provide .env variables to extension to override defaults

* Just adding some comments to webpack config

* Update defaults to real URLs in chain configs, comments

* Updated webpack to fix issue with missing quotes in build

* Very minor fix
  • Loading branch information
jurevans authored Dec 8, 2022
1 parent a43ce14 commit 066b67b
Showing 51 changed files with 610 additions and 742 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/deploy-wallet-at-merge-to-main.yml
Original file line number Diff line number Diff line change
@@ -28,10 +28,9 @@ jobs:
run: yarn build
env:
GENERATE_SOURCEMAP: false
REACT_APP_ALIAS: "Namada Testnet"
REACT_APP_CHAIN_ID: "qc-testnet-5.1.025a61165acd05e"
REACT_APP_LEDGER_URL: "https://d3brk13lbhxfdb.cloudfront.net/qc-testnet-5.1.025a61165acd05e"
REACT_APP_FAUCET: "atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3"
REACT_APP_NAMADA_ALIAS: "Namada Testnet"
REACT_APP_NAMADA_CHAIN_ID: "qc-testnet-5.1.025a61165acd05e"
REACT_APP_NAMADA_URL: "https://d3brk13lbhxfdb.cloudfront.net/qc-testnet-5.1.025a61165acd05e"

- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v1.2.3
7 changes: 3 additions & 4 deletions .github/workflows/deploy-wallet-at-pr.yml
Original file line number Diff line number Diff line change
@@ -78,10 +78,9 @@ jobs:
run: yarn build
env:
GENERATE_SOURCEMAP: false
REACT_APP_ALIAS: "Namada Testnet"
REACT_APP_CHAIN_ID: "qc-testnet-5.1.025a61165acd05e"
REACT_APP_LEDGER_URL: "https://d3brk13lbhxfdb.cloudfront.net/qc-testnet-5.1.025a61165acd05e"
REACT_APP_FAUCET: "atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3"
REACT_APP_NAMADA_ALIAS: "Namada Testnet"
REACT_APP_NAMADA_CHAIN_ID: "qc-testnet-5.1.025a61165acd05e"
REACT_APP_NAMADA_URL: "https://d3brk13lbhxfdb.cloudfront.net/qc-testnet-5.1.025a61165acd05e"

- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v1.2.3
2 changes: 2 additions & 0 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
"wasm:build": "./scripts/build.sh"
},
"dependencies": {
"@anoma/chains": "0.1.0",
"@anoma/components": "0.1.0",
"@anoma/crypto": "0.1.0",
"@anoma/rpc": "0.1.0",
@@ -53,6 +54,7 @@
"@types/uuid": "^8.3.4",
"@types/webextension-polyfill": "^0.9.0",
"copy-webpack-plugin": "^11.0.0",
"dotenv": "^16.0.3",
"eslint": "^8.23.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.5.0",
4 changes: 2 additions & 2 deletions apps/extension/src/App/Accounts/AddAccount.tsx
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import { AccountType, DerivedAccount } from "@anoma/types";
import { ExtensionRequester } from "extension";
import { Ports } from "router";
import { DeriveAccountMsg } from "background/keyring";
import { chains } from "config";
import { chains, defaultChainId } from "@anoma/chains";
import {
AddAccountContainer,
AddAccountForm,
@@ -109,7 +109,7 @@ const AddAccount: React.FC<Props> = ({

const bip44Prefix = "m/44";
const zip32Prefix = "m/32";
const { coinType } = chains[0].bip44;
const { coinType } = chains[defaultChainId].bip44;

useEffect(() => {
const isValid = validateAccount(
6 changes: 3 additions & 3 deletions apps/extension/src/background/index.ts
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ import {
ExtensionMessenger,
} from "extension";
import { Ports, KVPrefix } from "router";
import { chains } from "config";
import { defaultChainId, chains } from "@anoma/chains";
import { ChainsService, init as initChains } from "./chains";
import { KeyRingService, init as initKeyRing } from "./keyring";

@@ -31,8 +31,8 @@ const router = new ExtensionRouter(
router.addGuard(ExtensionGuards.checkOriginIsValid);
router.addGuard(ExtensionGuards.checkMessageIsInternal);

const chainsService = new ChainsService(store, chains);
const keyRingService = new KeyRingService(store);
const chainsService = new ChainsService(store, [chains[defaultChainId]]);
const keyRingService = new KeyRingService(store, defaultChainId);

// Initialize messages and handlers
initChains(router, chainsService);
14 changes: 8 additions & 6 deletions apps/extension/src/background/keyring/keyring.ts
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ import {
} from "@anoma/shared";
import { IStore, Store } from "@anoma/storage";
import { AccountType, Bip44Path, DerivedAccount, SignedTx } from "@anoma/types";
import { chains } from "config";
import { chains } from "@anoma/chains";
import { Crypto } from "./crypto";
import { KeyRingStatus, KeyStore } from "./types";

@@ -59,7 +59,7 @@ export class KeyRing {

constructor(
protected readonly kvStore: KVStore<KeyStore[]>,
protected readonly chainId: string = chains[0].chainId
protected readonly chainId: string
) {
this._keyStore = new Store(KEYSTORE_KEY, kvStore);
}
@@ -126,7 +126,7 @@ export class KeyRing {
try {
const mnemonic = Mnemonic.from_phrase(phrase);
const seed = mnemonic.to_seed();
const { coinType } = chains[0].bip44;
const { coinType } = chains[this.chainId].bip44;
const path = `m/44'/${coinType}'/0'/0`;
const bip44 = new HDWallet(seed);
const account = bip44.derive(path);
@@ -159,11 +159,12 @@ export class KeyRing {
public static deriveTransparentAccount(
seed: Uint8Array,
path: Bip44Path,
parentId: string
parentId: string,
chainId: string
): DerivedAccountInfo {
const { account, change, index = 0 } = path;
const root = "m/44'";
const { coinType } = chains[0].bip44;
const { coinType } = chains[chainId].bip44;
const derivationPath = [
root,
`${coinType}'`,
@@ -260,7 +261,8 @@ export class KeyRing {
const transparentAccount = KeyRing.deriveTransparentAccount(
seed,
path,
parentId
parentId,
this.chainId
);
id = transparentAccount.id;
address = transparentAccount.address;
7 changes: 5 additions & 2 deletions apps/extension/src/background/keyring/service.ts
Original file line number Diff line number Diff line change
@@ -9,8 +9,11 @@ import { IbcTransfer, Transfer } from "@anoma/shared";
export class KeyRingService {
private _keyRing: KeyRing;

constructor(protected readonly kvStore: KVStore<KeyStore[]>) {
this._keyRing = new KeyRing(kvStore);
constructor(
protected readonly kvStore: KVStore<KeyStore[]>,
protected readonly chainId: string
) {
this._keyRing = new KeyRing(kvStore, chainId);
}

lock(): { status: KeyRingStatus } {
50 changes: 0 additions & 50 deletions apps/extension/src/config/chains.ts

This file was deleted.

1 change: 0 additions & 1 deletion apps/extension/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from "./argon2";
export * from "./chains";
4 changes: 2 additions & 2 deletions apps/extension/src/provider/Anoma.test.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ import {

import { KVKeys } from "router";
import { init } from "test/init";
import { chains as defaultChains } from "../config";
import { chains as defaultChains } from "@anoma/chains";
import { chain, keyStore, NAM, password } from "./data.mock";
import { KeyRing, KEYSTORE_KEY } from "background/keyring";

@@ -53,7 +53,7 @@ describe("Anoma", () => {
iDBStore.set(KVKeys.Chains, [chain]);
const storedChains = await anoma.chains();

expect(storedChains).toEqual([...defaultChains, chain]);
expect(storedChains).toEqual([...Object.values(defaultChains), chain]);
});

it("should return all accounts", async () => {
46 changes: 13 additions & 33 deletions apps/extension/src/provider/data.mock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AccountType, Chain } from "@anoma/types";
import { AccountType, Chain, Extensions } from "@anoma/types";
import { KdfType, KeyStore } from "background/keyring";

export const NAM = {
@@ -15,41 +15,21 @@ export const NAM = {
};

export const chain: Chain = {
rpc: "http://localhost:26657",
rest: "http://localhost:1317",
chainId: "namada-test.XXXXXXXXXXXX",
chainName: "Namada Testnet",
stakeCurrency: {
coinDenom: "NAM",
coinMinimalDenom: "nam",
coinDecimals: 6,
},
alias: "Namada Testnet",
bech32Prefix: "atest",
bip44: {
coinType: 9999,
// coinType = testnet (all coins) - Slip-0044
// See: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
coinType: 1,
},
bech32Config: {
bech32PrefixAccAddr: "namada",
bech32PrefixAccPub: "namadapub",
bech32PrefixValAddr: "namadavaloper",
bech32PrefixValPub: "namadavaloperpub",
bech32PrefixConsAddr: "namadavalcons",
bech32PrefixConsPub: "namadavalconspub",
},
currencies: [NAM],
feeCurrencies: [
{
coinDenom: "NAM",
coinMinimalDenom: "nam",
coinDecimals: 6,
},
],
gasPriceStep: {
low: 0.01,
average: 0.025,
high: 0.03,
rpc: "http://localhost:26657",
chainId: "namada-75a7e12.69483d59a9fb174",
extension: Extensions["keplr"],
currency: {
token: "Namada",
symbol: "NAM",
gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, // Optional
},
features: ["ibc-transfer"],
beta: false,
};

export const keyStore: KeyStore = {
18 changes: 12 additions & 6 deletions apps/extension/src/test/init.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import {
ExtensionRequester,
} from "../extension";
import { Ports, KVPrefix } from "../router";
import { chains } from "../config";
import { chains } from "@anoma/chains";
import { ChainsService, init as initChains } from "../background/chains";
import {
KeyRingService,
@@ -37,8 +37,8 @@ export const init = (): {
anoma: Anoma;
iDBStore: KVStoreMock<Chain[] | KeyStore[]>;
extStore: KVStoreMock<number>;
chainsService: ChainsService,
keyRingService: KeyRingService
chainsService: ChainsService;
keyRingService: KeyRingService;
} => {
const messenger = new ExtensionMessengerMock();

@@ -58,8 +58,14 @@ export const init = (): {
extStore
);

const chainsService = new ChainsService(iDBStore as KVStore<Chain[]>, chains);
const keyRingService = new KeyRingService(iDBStore as KVStore<KeyStore[]>);
const chainsService = new ChainsService(
iDBStore as KVStore<Chain[]>,
Object.values(chains)
);
const keyRingService = new KeyRingService(
iDBStore as KVStore<KeyStore[]>,
"namada-test.XXXXXXXX"
);

// Initialize messages and handlers
initChains(router, chainsService);
@@ -75,6 +81,6 @@ export const init = (): {
iDBStore,
extStore,
chainsService,
keyRingService
keyRingService,
};
};
46 changes: 45 additions & 1 deletion apps/extension/webpack.config.js
Original file line number Diff line number Diff line change
@@ -6,7 +6,25 @@ const ExtensionReloader = require("webpack-extension-reloader");
const createStyledComponentsTransformer =
require("typescript-plugin-styled-components").default;

const { NODE_ENV, TARGET } = process.env;
// Load .env from namada-interface:
require("dotenv").config({ path: "../namada-interface/.env" });

const {
NODE_ENV,
TARGET,
// React .env variables from interface for shared chain configuration:
REACT_APP_NAMADA_ALIAS,
REACT_APP_NAMADA_CHAIN_ID,
REACT_APP_NAMADA_URL,
REACT_APP_NAMADA_BECH32_PREFIX,
REACT_APP_COSMOS_ALIAS,
REACT_APP_COSMOS_CHAIN_ID,
REACT_APP_COSMOS_URL,
REACT_APP_OSMOSIS_ALIAS,
REACT_APP_OSMOSIS_CHAIN_ID,
REACT_APP_OSMOSIS_URL,
} = process.env;

const MANIFEST_VERSION = TARGET === "firefox" ? "v2" : "v3";
const MANIFEST_BASE_PATH = `./src/manifest/_base.json`;
const MANIFEST_BASE_VERSION_PATH = `./src/manifest/${MANIFEST_VERSION}/_base.json`;
@@ -28,6 +46,26 @@ const copyPatterns = [
},
];

// Set up environment values
const env = {};
const envVariables = {
REACT_APP_NAMADA_ALIAS,
REACT_APP_NAMADA_CHAIN_ID,
REACT_APP_NAMADA_URL,
REACT_APP_NAMADA_BECH32_PREFIX,
REACT_APP_COSMOS_ALIAS,
REACT_APP_COSMOS_CHAIN_ID,
REACT_APP_COSMOS_URL,
REACT_APP_OSMOSIS_ALIAS,
REACT_APP_OSMOSIS_CHAIN_ID,
REACT_APP_OSMOSIS_URL,
};

// Stringify to ensure values are wrapped in quotes
for (const key in envVariables) {
env[key] = JSON.stringify(envVariables[key]);
}

const plugins = [
new CopyPlugin({
patterns: copyPatterns,
@@ -41,6 +79,12 @@ const plugins = [
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
}),
// Provide environment variables to extension:
new webpack.DefinePlugin({
process: {
env,
},
}),
];

if (NODE_ENV === "development") {
Loading

0 comments on commit 066b67b

Please sign in to comment.