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(phantom-and-oyl): support phantom and oyl wallet #402

Merged
merged 2 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
| Xverse | ✅ | ✅ |
| Magic Eden | ✅ | ✅ |
| Leather | ✅ | ✅ |
| Phantom | ✅ | ✅ |
| Oyl | ✅ | ✅ |

## Quick Start

Expand Down
2 changes: 1 addition & 1 deletion packages/ord-connect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
]
},
"peerDependencies": {
"@ordzaar/ordit-sdk": "^4.1.1",
"@ordzaar/ordit-sdk": "^4.2.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/ord-connect/src/assets/oyl-wallet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions packages/ord-connect/src/assets/phantom-wallet.svg
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 @@ -7,6 +7,8 @@ import LeatherWalletIcon from "../../assets/leather-wallet.svg";
import LogoutIcon from "../../assets/logout.svg";
import MagicEdenIcon from "../../assets/magiceden-wallet.svg";
import OKXWalletIcon from "../../assets/okx-wallet.svg";
import OylWalletIcon from "../../assets/oyl-wallet.svg";
import PhantomWalletIcon from "../../assets/phantom-wallet.svg";
import UnisatWalletIcon from "../../assets/unisat-wallet.svg";
import XverseWalletIcon from "../../assets/xverse-wallet.svg";
import {
Expand All @@ -22,6 +24,8 @@ const WALLET_TO_ICON: Record<Wallet, string> = {
[Wallet.XVERSE]: XverseWalletIcon,
[Wallet.LEATHER]: LeatherWalletIcon,
[Wallet.OKX]: OKXWalletIcon,
[Wallet.PHANTOM]: PhantomWalletIcon,
[Wallet.OYL]: OylWalletIcon,
} as const;

interface PostConnectButtonProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const WALLET_TO_NAME: Record<Wallet, string> = {
[Wallet.XVERSE]: "Xverse",
[Wallet.LEATHER]: "Leather",
[Wallet.OKX]: "OKX",
[Wallet.PHANTOM]: "Phantom",
[Wallet.OYL]: "Oyl",
} as const;

export interface WalletButtonProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import { getAddresses as getLeatherAddresses } from "@ordzaar/ordit-sdk/leather";
import { getAddresses as getMagicEdenAddress } from "@ordzaar/ordit-sdk/magiceden";
import { getAddresses as getOKXAddresses } from "@ordzaar/ordit-sdk/okx";
import { getAddresses as getOylAddresses } from "@ordzaar/ordit-sdk/oyl";
import { getAddresses as getPhantomAddresses } from "@ordzaar/ordit-sdk/phantom";
import { getAddresses as getUnisatAddresses } from "@ordzaar/ordit-sdk/unisat";
import { getAddresses as getXverseAddresses } from "@ordzaar/ordit-sdk/xverse";

Expand All @@ -31,6 +33,8 @@
[Wallet.UNISAT]: "https://unisat.io/download", // their www subdomain doesn't work
[Wallet.XVERSE]: "https://www.xverse.app/download",
[Wallet.LEATHER]: "https://leather.io/install-extension",
[Wallet.PHANTOM]: "https://phantom.com/download",
[Wallet.OYL]: "https://www.oyl.io/#get-wallet",
};

const connectWallet = async (
Expand Down Expand Up @@ -209,6 +213,84 @@
},
};
}
case Wallet.PHANTOM: {
const phantom = await getPhantomAddresses(network);
if (!phantom || phantom.length < 1) {
throw new Error("Phantom via Ordit returned no addresses");
}

const paymentsAddress = phantom.find(
(walletAddress) => walletAddress.format === "segwit",
);

if (!paymentsAddress) {
throw new Error("Phantom via Ordit did not return a Segwit address");
}

const ordinalsAddress = phantom.find(
(walletAddress) => walletAddress.format === "taproot",
);

if (!ordinalsAddress) {
throw new Error("Phantom via Ordit did not return a Taproot address");
}

return {
address: {
ordinals: ordinalsAddress.address,
payments: paymentsAddress.address,
},
publicKey: {
ordinals: ordinalsAddress.publicKey,
payments: paymentsAddress.publicKey,
},
format: {
ordinals: ordinalsAddress.format,
payments: paymentsAddress.format,
},
};
}
case Wallet.OYL: {
const oyl = await getOylAddresses(network);
if (!oyl || oyl.length < 1) {
throw new Error("Oyl via Ordit returned no addresses");
}

const paymentsAddress = oyl.find(
(walletAddress) =>
walletAddress.format === "p2sh-p2wpkh" ||
walletAddress.format === "segwit",
);

if (!paymentsAddress) {
throw new Error(
"Oyl via Ordit did not return a P2SH or Segwit address",
);
}

const ordinalsAddress = oyl.find(
(walletAddress) => walletAddress.format === "taproot",
);

if (!ordinalsAddress) {
throw new Error("Oyl via Ordit did not return a Taproot address");
}

return {
address: {
ordinals: ordinalsAddress.address,
payments: paymentsAddress.address,
},
publicKey: {
ordinals: ordinalsAddress.publicKey,
payments: paymentsAddress.publicKey,
},
format: {
ordinals: ordinalsAddress.format,
payments: paymentsAddress.format,
},
};
}
default:
throw new Error("Invalid wallet");
}
Expand Down Expand Up @@ -243,7 +325,7 @@
| Error,
) => {
onUserError(err.message ?? err.toString());
console.error(`Error while connecting to ${walletProvider} wallet`, err);

Check warning on line 328 in packages/ord-connect/src/components/SelectWalletModal/hooks/useConnect.ts

View workflow job for this annotation

GitHub Actions / Lint - Typescript and ESLint

Unexpected console statement
disconnectWallet();

if (err instanceof BrowserWalletNotInstalledError) {
Expand Down Expand Up @@ -322,7 +404,7 @@
window.unisat.removeListener("accountsChanged", listener);
}
};
}, [connectedWallet]);

Check warning on line 407 in packages/ord-connect/src/components/SelectWalletModal/hooks/useConnect.ts

View workflow job for this annotation

GitHub Actions / Lint - Typescript and ESLint

React Hook useEffect has missing dependencies: 'connectedAddress', 'connectedFormat', 'connectedPublicKey', 'disconnectWallet', and 'onConnect'. Either include them or remove the dependency array

return { connectWallet: onConnect };
}
18 changes: 18 additions & 0 deletions packages/ord-connect/src/components/SelectWalletModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import CloseModalIcon from "../../assets/close-modal.svg";
import LeatherWalletIcon from "../../assets/leather-wallet.svg";
import MagicEdenWalletIcon from "../../assets/magiceden-wallet.svg";
import OKXWalletIcon from "../../assets/okx-wallet.svg";
import OylWalletIcon from "../../assets/oyl-wallet.svg";
import PhantomWalletIcon from "../../assets/phantom-wallet.svg";
import UnisatWalletIcon from "../../assets/unisat-wallet.svg";
import XverseWalletIcon from "../../assets/xverse-wallet.svg";
import {
Expand Down Expand Up @@ -95,6 +97,22 @@ export function SelectWalletModal({
order: 24,
chains: [Chain.BITCOIN],
},
{
wallet: Wallet.PHANTOM,
onConnect: () => connectWallet(Wallet.PHANTOM),
icon: PhantomWalletIcon,
hidden: isMobile,
order: 25,
chains: [Chain.BITCOIN],
},
{
wallet: Wallet.OYL,
onConnect: () => connectWallet(Wallet.OYL),
icon: OylWalletIcon,
hidden: isMobile,
order: 26,
chains: [Chain.BITCOIN],
},
];

const walletList = ALL_WALLETS.filter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
.ord-connect-wallet-modal .wallet-icon {
width: 32px;
height: 32px;
border-radius: 9999px;
}

.ord-connect-wallet-modal .wallet-option {
Expand Down Expand Up @@ -286,6 +287,7 @@
.ord-connect-wallet-modal .wallet-icon {
width: 40px;
height: 40px;
border-radius: 9999px;
}

.ord-connect-wallet-modal .wallet-option-label {
Expand Down
12 changes: 12 additions & 0 deletions packages/ord-connect/src/lib/signMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
} from "@ordzaar/ordit-sdk/leather";
import { signMessage as signMagicEdenMessage } from "@ordzaar/ordit-sdk/magiceden";
import { signMessage as signOKXMessage } from "@ordzaar/ordit-sdk/okx";
import { signMessage as signOylMessage } from "@ordzaar/ordit-sdk/oyl";
import { signMessage as signPhantomMessage } from "@ordzaar/ordit-sdk/phantom";
import { signMessage as signUnisatMessage } from "@ordzaar/ordit-sdk/unisat";
import { signMessage as signXverseMessage } from "@ordzaar/ordit-sdk/xverse";

Expand Down Expand Up @@ -72,5 +74,15 @@ export default async function signMessage({
return base64;
}

if (wallet === Wallet.PHANTOM) {
const { base64 } = await signPhantomMessage(message, address, network);
return base64;
}

if (wallet === Wallet.OYL) {
const { base64 } = await signOylMessage(message, address, network);
return base64;
}

throw new Error("Invalid wallet selected");
}
34 changes: 34 additions & 0 deletions packages/ord-connect/src/lib/signPsbt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Psbt } from "bitcoinjs-lib";
import { signPsbt as signLeatherPsbt } from "@ordzaar/ordit-sdk/leather";
import { signPsbt as signMagicEdenPsbt } from "@ordzaar/ordit-sdk/magiceden";
import { signPsbt as signOKXPsbt } from "@ordzaar/ordit-sdk/okx";
import { signPsbt as signOylPsbt } from "@ordzaar/ordit-sdk/oyl";
import { signPsbt as signPhantomPsbt } from "@ordzaar/ordit-sdk/phantom";
import { signPsbt as signUnisatPsbt } from "@ordzaar/ordit-sdk/unisat";
import { signPsbt as signXversePsbt } from "@ordzaar/ordit-sdk/xverse";

Expand Down Expand Up @@ -124,6 +126,38 @@ export default async function signPsbt({
return signedOKXPsbt;
}

if (wallet === Wallet.PHANTOM) {
const signedPhantomPsbt = await signPhantomPsbt(psbt, {
finalize,
extractTx,
network,
inputsToSign: options?.inputsToSign ?? [
{
address,
signingIndexes: options?.signingIndexes ?? getAllInputIndices(), // If signingIndexes is not provided, just sign everything
sigHash: options?.sigHash,
},
],
});
return signedPhantomPsbt;
}

if (wallet === Wallet.OYL) {
const signedOylPsbt = await signOylPsbt(psbt, {
finalize,
extractTx,
network,
inputsToSign: options?.inputsToSign ?? [
{
address,
signingIndexes: options?.signingIndexes ?? getAllInputIndices(), // If signingIndexes is not provided, just sign everything
sigHash: options?.sigHash,
},
],
});
return signedOylPsbt;
}

// else throw error
throw new Error("Invalid wallet selected");
}
2 changes: 2 additions & 0 deletions packages/ord-connect/src/providers/OrdConnectProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,23 @@

import { useLocalStorage } from "../hooks/useLocalStorage";

export enum Network {

Check warning on line 14 in packages/ord-connect/src/providers/OrdConnectProvider.tsx

View workflow job for this annotation

GitHub Actions / Build (Apps & Packages)

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
MAINNET = "mainnet",
TESTNET = "testnet",
SIGNET = "signet",
}

export enum Wallet {

Check warning on line 20 in packages/ord-connect/src/providers/OrdConnectProvider.tsx

View workflow job for this annotation

GitHub Actions / Build (Apps & Packages)

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
UNISAT = "unisat",
XVERSE = "xverse",
MAGICEDEN = "magiceden",
LEATHER = "leather",
OKX = "okx",
PHANTOM = "phantom",
OYL = "oyl",
}

export enum Chain {

Check warning on line 30 in packages/ord-connect/src/providers/OrdConnectProvider.tsx

View workflow job for this annotation

GitHub Actions / Build (Apps & Packages)

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
BITCOIN = "bitcoin",
FRACTAL_BITCOIN = "fractal-bitcoin",
}
Expand Down Expand Up @@ -203,7 +205,7 @@
);
}

export function useOrdConnect() {

Check warning on line 208 in packages/ord-connect/src/providers/OrdConnectProvider.tsx

View workflow job for this annotation

GitHub Actions / Build (Apps & Packages)

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components
const context = useContext(OrdConnectContext);

if (!context) {
Expand Down
16 changes: 8 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading