Skip to content

Commit

Permalink
feat: bitcoin (#568)
Browse files Browse the repository at this point in the history
* feat: implements bitcoin signet support in example dapp

* feat: implements bitcoin signet in example wallet

* fix: prettier

* fix: adds tiny-secp256k1 to packages

* chore: cleanup console logs

* chore: cleanup

* chore: rm console log

* chore: dapp rework with btc specs

* chore: parse addreses result

* chore: sets bifrost wallet link

* feat: lists all addresses on getaccountAddresses response

* feat: implements new btc spec

* feat: adds ordninals address handling

* feat: sets addresses in session props

* fix: types

* refactor: cleanup

* fix: build

* feat: added btc mainnet

* fix: explorer mainnet & testnet urls

---------

Co-authored-by: Gancho Radkov <ganchoradkov@gmail.com>
  • Loading branch information
ganchoradkov and Gancho Radkov authored Oct 29, 2024
1 parent ad24028 commit 59487b2
Show file tree
Hide file tree
Showing 37 changed files with 1,896 additions and 48 deletions.
3 changes: 3 additions & 0 deletions advanced/dapps/react-dapp-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@kadena/types": "^0.6.0",
"@multiversx/sdk-core": "12.18.0",
"@multiversx/sdk-wallet": "4.2.0",
"@noble/curves": "^1.6.0",
"@polkadot/util-crypto": "^10.1.2",
"@solana/web3.js": "^1.36.0",
"@walletconnect/encoding": "^1.0.1",
Expand All @@ -26,6 +27,8 @@
"@walletconnect/utils": "2.16.1",
"@web3modal/standalone": "2.4.3",
"axios": "^1.0.0",
"bitcoinjs-lib": "^6.1.5",
"bitcoinjs-message": "^2.2.0",
"blockies-ts": "^1.0.0",
"bs58": "^5.0.0",
"cosmos-wallet": "^1.2.0",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions advanced/dapps/react-dapp-v2/src/chains/bip122.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { NamespaceMetadata, ChainMetadata, ChainsMap } from "../helpers";

export const BIP122_MAINNET = "000000000019d6689c085ae165831e93";
export const BIP122_TESTNET = "000000000933ea01ad0ee984209779ba";

export const BtcChainData: ChainsMap = {
[BIP122_MAINNET]: {
id: `bip122:${BIP122_MAINNET}`,
name: "BTC Mainnet",
rpc: [],
slip44: 0,
testnet: false,
},
[BIP122_TESTNET]: {
id: `bip122:${BIP122_TESTNET}`,
name: "BTC Testnet",
rpc: [],
slip44: 501,
testnet: true,
},
};

export const BtcMetadata: NamespaceMetadata = {
[BIP122_MAINNET]: {
logo: "/assets/btc-testnet.png",
rgb: "247, 147, 25",
},
[BIP122_TESTNET]: {
logo: "/assets/btc-testnet.png",
rgb: "247, 147, 25",
},
};

export function getChainMetadata(chainId: string): ChainMetadata {
const reference = chainId.split(":")[1];
const metadata = BtcMetadata[reference];
if (typeof metadata === "undefined") {
throw new Error(`No chain metadata found for chainId: ${chainId}`);
}
return metadata;
}
3 changes: 3 additions & 0 deletions advanced/dapps/react-dapp-v2/src/chains/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as multiversx from "./multiversx";
import * as tron from "./tron";
import * as tezos from "./tezos";
import * as kadena from "./kadena";
import * as bip122 from "./bip122";

import { ChainMetadata, ChainRequestRender } from "../helpers";

Expand All @@ -33,6 +34,8 @@ export function getChainMetadata(chainId: string): ChainMetadata {
return tron.getChainMetadata(chainId);
case "tezos":
return tezos.getChainMetadata(chainId);
case "bip122":
return bip122.getChainMetadata(chainId);
default:
throw new Error(`No metadata handler for namespace ${namespace}`);
}
Expand Down
5 changes: 5 additions & 0 deletions advanced/dapps/react-dapp-v2/src/components/Asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { getChainMetadata } from "../chains";
const xdaiLogo = getChainMetadata("eip155:100").logo;
const maticLogo = getChainMetadata("eip155:137").logo;
const kadenaLogo = getChainMetadata("kadena:testnet04").logo;
const btcLogo = getChainMetadata(
"bip122:000000000933ea01ad0ee984209779ba"
).logo;

const SAsset = styled.div`
width: 100%;
Expand Down Expand Up @@ -48,6 +51,8 @@ function getAssetIcon(asset: AssetData): JSX.Element {
return <Icon src={maticLogo} />;
case "kda":
return <Icon src={kadenaLogo} />;
case "btc":
return <Icon src={btcLogo} />;
default:
return <Icon src={"/assets/eth20.svg"} />;
}
Expand Down
14 changes: 14 additions & 0 deletions advanced/dapps/react-dapp-v2/src/constants/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const DEFAULT_MAIN_CHAINS = [
"tron:0x2b6653dc",
"tezos:mainnet",
"kadena:mainnet01",
"bip122:000000000019d6689c085ae165831e93",
];

export const DEFAULT_TEST_CHAINS = [
Expand All @@ -38,6 +39,7 @@ export const DEFAULT_TEST_CHAINS = [
"tron:0xcd8690dc",
"tezos:testnet",
"kadena:testnet04",
"bip122:000000000933ea01ad0ee984209779ba",
];

export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS];
Expand Down Expand Up @@ -272,6 +274,18 @@ export enum DEFAULT_KADENA_METHODS {
}

export enum DEFAULT_KADENA_EVENTS {}
/**
* BITCOIN
*/
export enum DEFAULT_BIP122_METHODS {
BIP122_SEND_TRANSACTION = "sendTransfer",
BIP122_GET_ACCOUNT_ADDRESSES = "getAccountAddresses",
BIP122_SIGN_MESSAGE = "signMessage",
BIP122_SIGN_PSBT = "signPsbt",
}
export enum DEFAULT_BIP122_EVENTS {
BIP122_ADDRESS_CHANGED = "bip122_addressesChanged",
}

export const REGIONALIZED_RELAYER_ENDPOINTS: RelayerType[] = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { CosmosChainData } from "../chains/cosmos";
import { EIP155ChainData } from "../chains/eip155";
import { TezosChainData } from "../chains/tezos";
import { KadenaChainData } from "../chains/kadena";
import { BtcChainData } from "../chains/bip122";

/**
* Types
Expand Down Expand Up @@ -73,6 +74,9 @@ export function ChainDataContextProvider({
case "kadena":
chains = KadenaChainData;
break;
case "bip122":
chains = BtcChainData;
break;
default:
console.error("Unknown chain namespace: ", namespace);
}
Expand Down
36 changes: 22 additions & 14 deletions advanced/dapps/react-dapp-v2/src/contexts/ClientContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ interface IContext {
setChains: any;
setRelayerRegion: any;
origin: string;
setAccounts: any;
}

/**
Expand All @@ -63,6 +64,16 @@ const web3Modal = new Web3Modal({
projectId: DEFAULT_PROJECT_ID,
themeMode: "light",
walletConnectVersion: 2,
mobileWallets: [
{
id: "bifrost",
name: "Bifrost Wallet",
links: {
native: "bifrostwallet://",
universal: "https://bifrostwallet.com",
},
},
],
});

/**
Expand Down Expand Up @@ -106,7 +117,6 @@ export function ClientContextProvider({
const [namespace, reference, address] = account.split(":");
const chainId = `${namespace}:${reference}`;
const assets = await apiGetAccountBalance(address, chainId);

return { account, assets: [assets] };
})
);
Expand All @@ -123,6 +133,11 @@ export function ClientContextProvider({
}
};

useMemo(() => {
if (!accounts.length) return;
getAccountBalances(accounts);
}, [accounts]);

const onSessionConnected = useCallback(
async (_session: SessionTypes.Struct) => {
const allNamespaceAccounts = Object.values(_session.namespaces)
Expand All @@ -147,26 +162,17 @@ export function ClientContextProvider({
}
console.log("connect, pairing topic is:", pairing?.topic);
try {
const requiredNamespaces = getRequiredNamespaces(chains);
console.log(
"requiredNamespaces config for connect:",
requiredNamespaces
);
const optionalNamespaces = getOptionalNamespaces(chains);
console.log(
"optionalNamespaces config for connect:",
optionalNamespaces
);
const namespacesToRequest = getRequiredNamespaces(chains);
const { uri, approval } = await client.connect({
pairingTopic: pairing?.topic,
requiredNamespaces,
optionalNamespaces,
requiredNamespaces: {},
optionalNamespaces: namespacesToRequest,
});

// Open QRCode modal if a URI was returned (i.e. we're not connecting an existing pairing).
if (uri) {
// Create a flat array of all requested chains across namespaces.
const standaloneChains = Object.values(requiredNamespaces)
const standaloneChains = Object.values(namespacesToRequest)
.map((namespace) => namespace.chains)
.flat() as string[];

Expand Down Expand Up @@ -375,6 +381,7 @@ export function ClientContextProvider({
setChains,
setRelayerRegion,
origin,
setAccounts,
}),
[
pairings,
Expand All @@ -392,6 +399,7 @@ export function ClientContextProvider({
setChains,
setRelayerRegion,
origin,
setAccounts,
]
);

Expand Down
Loading

0 comments on commit 59487b2

Please sign in to comment.