Skip to content

Commit

Permalink
Merge branch 'v2.0' into v2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ganchoradkov authored Jul 29, 2024
2 parents fa2198a + 01bc389 commit e0ec252
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
6 changes: 6 additions & 0 deletions providers/universal-provider/src/UniversalProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import PolkadotProvider from "./providers/polkadot";
import Eip155Provider from "./providers/eip155";
import SolanaProvider from "./providers/solana";
import CosmosProvider from "./providers/cosmos";
import AlgorandProvider from "./providers/algorand";
import CardanoProvider from "./providers/cardano";
import ElrondProvider from "./providers/elrond";
import MultiversXProvider from "./providers/multiversx";
Expand Down Expand Up @@ -339,6 +340,11 @@ export class UniversalProvider implements IUniversalProvider {
namespace: combinedNamespace,
});
break;
case "algorand":
this.rpcProviders[namespace] = new AlgorandProvider({
namespace: combinedNamespace,
});
break;
case "solana":
this.rpcProviders[namespace] = new SolanaProvider({
namespace: combinedNamespace,
Expand Down
125 changes: 125 additions & 0 deletions providers/universal-provider/src/providers/algorand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import HttpConnection from "@walletconnect/jsonrpc-http-connection";
import { JsonRpcProvider } from "@walletconnect/jsonrpc-provider";
import Client from "@walletconnect/sign-client";
import { EngineTypes, SessionTypes } from "@walletconnect/types";
import EventEmitter from "events";
import { PROVIDER_EVENTS } from "../constants";
import {
IProvider,
RequestParams,
RpcProvidersMap,
SessionNamespace,
SubProviderOpts,
} from "../types";
import { getGlobal, getRpcUrl } from "../utils";

class AlgorandProvider implements IProvider {
public name = "algorand";
public client: Client;
public httpProviders: RpcProvidersMap;
public events: EventEmitter;
public namespace: SessionNamespace;
public chainId: string;

constructor(opts: SubProviderOpts) {
this.namespace = opts.namespace;
this.events = getGlobal("events");
this.client = getGlobal("client");
this.chainId = this.getDefaultChain();
this.httpProviders = this.createHttpProviders();
}

public updateNamespace(namespace: SessionTypes.Namespace) {
this.namespace = Object.assign(this.namespace, namespace);
}

public requestAccounts(): string[] {
return this.getAccounts();
}

public request<T = unknown>(args: RequestParams): Promise<T> {
if (this.namespace.methods.includes(args.request.method)) {
return this.client.request(args as EngineTypes.RequestParams);
}
return this.getHttpProvider().request(args.request);
}

public setDefaultChain(chainId: string, rpcUrl?: string | undefined) {
// http provider exists so just set the chainId
if (!this.httpProviders[chainId]) {
const rpc =
rpcUrl || getRpcUrl(`${this.name}:${chainId}`, this.namespace, this.client.core.projectId);
if (!rpc) {
throw new Error(`No RPC url provided for chainId: ${chainId}`);
}
this.setHttpProvider(chainId, rpc);
}
this.chainId = chainId;
this.events.emit(PROVIDER_EVENTS.DEFAULT_CHAIN_CHANGED, `${this.name}:${this.chainId}`);
}

public getDefaultChain(): string {
if (this.chainId) return this.chainId;
if (this.namespace.defaultChain) return this.namespace.defaultChain;

const chainId = this.namespace.chains[0];
if (!chainId) throw new Error(`ChainId not found`);

return chainId.split(":")[1];
}

// --------- PRIVATE --------- //

private getAccounts(): string[] {
const accounts = this.namespace.accounts;
if (!accounts) {
return [];
}

return [
...new Set(
accounts
// get the accounts from the active chain
.filter((account) => account.split(":")[1] === this.chainId.toString())
// remove namespace & chainId from the string
.map((account) => account.split(":")[2]),
),
];
}

private createHttpProviders(): RpcProvidersMap {
const http = {};
this.namespace.chains.forEach((chain) => {
http[chain] = this.createHttpProvider(chain, this.namespace.rpcMap?.[chain]);
});
return http;
}

private getHttpProvider(): JsonRpcProvider {
const chain = `${this.name}:${this.chainId}`;
const http = this.httpProviders[chain];
if (typeof http === "undefined") {
throw new Error(`JSON-RPC provider for ${chain} not found`);
}
return http;
}

private setHttpProvider(chainId: string, rpcUrl?: string): void {
const http = this.createHttpProvider(chainId, rpcUrl);
if (http) {
this.httpProviders[chainId] = http;
}
}

private createHttpProvider(
chainId: string,
rpcUrl?: string | undefined,
): JsonRpcProvider | undefined {
const rpc = rpcUrl || getRpcUrl(chainId, this.namespace, this.client.core.projectId);
if (typeof rpc === "undefined") return undefined;
const http = new JsonRpcProvider(new HttpConnection(rpc, getGlobal("disableProviderPing")));
return http;
}
}

export default AlgorandProvider;
1 change: 1 addition & 0 deletions providers/universal-provider/src/providers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * as AlgorandProvider from "./algorand";
export * as Eip155Provider from "./eip155";
export * as SolanaProvider from "./solana";
export * as CosmosProvider from "./cosmos";
Expand Down
10 changes: 10 additions & 0 deletions providers/universal-provider/test/shared/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const EIP155_TEST_METHODS = [
"wallet_switchEthereumChain",
];

export const ALGORAND_TEST_METHODS = ["algo_signTxn"];
export const COSMOS_TEST_METHODS = ["cosmos_signDirect", "cosmos_signAmino"];
export const ELROND_TEST_METHODS = ["erd_signTransaction", "erd_signLoginToken"];
export const MULTIVERSX_TEST_METHODS = ["multiversx_signTransaction", "multiversx_signMessage"];
Expand All @@ -89,6 +90,15 @@ export const TEST_NAMESPACES_CONFIG = {
[CHAIN_ID_B]: RPC_URL_B,
},
},
algorand: {
methods: ALGORAND_TEST_METHODS,
chains: [`algorand:${CHAIN_ID}`, `algorand:${CHAIN_ID_B}`],
events: ["chainChanged", "accountsChanged"],
rpcMap: {
[CHAIN_ID]: RPC_URL,
[CHAIN_ID_B]: RPC_URL_B,
},
},
cosmos: {
methods: COSMOS_TEST_METHODS,
chains: [`cosmos:${CHAIN_ID}`, `cosmos:${CHAIN_ID_B}`],
Expand Down

0 comments on commit e0ec252

Please sign in to comment.