Skip to content
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
4 changes: 2 additions & 2 deletions etc/sdk-solana.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ export function decodeStealthMetaAddress(metaAddress: string): StealthMetaAddres
// @public (undocumented)
export const DEPLOYMENTS: Record<string, SolanaChainDeployment>;

// Warning: (ae-forgotten-export) The symbol "StealthKeys_2" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "StealthKeys$1" needs to be exported by the entry point index.d.ts
//
// @public
export function deriveStealthKeys(signature: Uint8Array): StealthKeys_2;
export function deriveStealthKeys(signature: Uint8Array): StealthKeys$1;

// @public
export function deriveStealthPrivateScalar(spendingScalar: bigint, viewingKey: Uint8Array, ephemeralPubKey: Uint8Array): bigint;
Expand Down
9 changes: 8 additions & 1 deletion etc/sdk-stellar.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,15 +707,22 @@ export interface WebAuthnCredentialsContainer {
get(options: Record<string, unknown>): Promise<WebAuthnPRFAssertion | null>;
}

// Warning: (ae-forgotten-export) The symbol "StellarWalletAdapter" needs to be exported by the entry point index.d.ts
//
// @public
export class WebAuthnPasskeyStealthSigner implements StellarStealthSigner {
export class WebAuthnPasskeyStealthSigner implements StellarStealthSigner, StellarWalletAdapter {
constructor(options: WebAuthnPasskeyStealthSignerOptions);
// (undocumented)
readonly chain: "stellar";
// (undocumented)
getAddress(): Promise<string>;
// (undocumented)
signMessage(message: Uint8Array): Promise<Uint8Array>;
}

// @public
export interface WebAuthnPasskeyStealthSignerOptions {
address?: string;
credentialId: Uint8Array;
credentials?: WebAuthnCredentialsContainer;
rpId?: string;
Expand Down
164 changes: 148 additions & 16 deletions etc/sdk.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ export interface Balance {
tokens: Record<string, string>;
}

// @public
export interface BaseWalletAdapter<TChain extends WalletAdapterChain, TSignature> {
// (undocumented)
readonly chain: TChain;
// (undocumented)
getAddress(): Promise<string>;
// (undocumented)
signMessage(message: Uint8Array): Promise<TSignature>;
}

// @public (undocumented)
export enum Chain {
// (undocumented)
Expand Down Expand Up @@ -75,13 +85,13 @@ export interface CkbChainInput {
// (undocumented)
source: AsyncIterable<StealthCell>;
// (undocumented)
spendingKey: HexString;
spendingKey: HexString_2;
// (undocumented)
spendingPubKey: HexString;
// Warning: (ae-forgotten-export) The symbol "HexString" needs to be exported by the entry point index.d.ts
spendingPubKey: HexString_2;
// Warning: (ae-forgotten-export) The symbol "HexString_2" needs to be exported by the entry point index.d.ts
//
// (undocumented)
viewingKey: HexString;
viewingKey: HexString_2;
}

// @public (undocumented)
Expand All @@ -105,6 +115,33 @@ export interface Conversation {
updatedAt: string;
}

// @public
export function createFreighterWalletAdapter(wallet: FreighterWalletApi): FreighterWalletAdapter;

// @public
export function createSolanaWalletAdapter(wallet: SolanaWalletAdapterLike): SolanaWalletAdapter;

// @public
export function createViemWalletAdapter(client: ViemWalletClient): ViemWalletAdapter;

// Warning: (ae-forgotten-export) The symbol "StealthKeys$1" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export function deriveStealthKeysFromWallet(adapter: StellarWalletAdapter): Promise<StealthKeys$1>;

// Warning: (ae-forgotten-export) The symbol "StealthKeys" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export function deriveStealthKeysFromWallet(adapter: EvmWalletAdapter): Promise<StealthKeys>;

// Warning: (ae-forgotten-export) The symbol "StealthKeys_2" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export function deriveStealthKeysFromWallet(adapter: SolanaChainWalletAdapter): Promise<StealthKeys_2>;

// @public (undocumented)
export function deriveStealthKeysFromWallet(adapter: WalletAdapter): Promise<StealthKeys$1 | StealthKeys | StealthKeys_2>;

// @public (undocumented)
export class ECDHFailedError extends WraithCryptoError {
constructor(reason: string);
Expand All @@ -119,13 +156,45 @@ export interface EvmChainInput {
// (undocumented)
source: AsyncIterable<Announcement>;
// (undocumented)
spendingKey: HexString_2;
spendingKey: HexString;
// (undocumented)
spendingPubKey: HexString_2;
// Warning: (ae-forgotten-export) The symbol "HexString_2" needs to be exported by the entry point index.d.ts
spendingPubKey: HexString;
// Warning: (ae-forgotten-export) The symbol "HexString" needs to be exported by the entry point index.d.ts
//
// (undocumented)
viewingKey: HexString_2;
viewingKey: HexString;
}

// @public
export type EvmWalletAdapter = BaseWalletAdapter<'evm', HexString>;

// @public
export class FreighterWalletAdapter implements StellarWalletAdapter {
constructor(wallet: FreighterWalletApi);
// (undocumented)
readonly chain: "stellar";
// (undocumented)
getAddress(): Promise<string>;
// (undocumented)
signMessage(message: Uint8Array): Promise<Uint8Array>;
}

// @public
export interface FreighterWalletApi {
// (undocumented)
getAddress(): Promise<string | {
address?: string;
error?: string | {
message?: string;
};
}>;
// (undocumented)
signMessage(message: string): Promise<{
signedMessage?: Uint8Array | string;
error?: string | {
message?: string;
};
}>;
}

// @public (undocumented)
Expand Down Expand Up @@ -212,12 +281,12 @@ export type MatchedAnnouncement = {
chain: 'stellar';
timestamp: number;
seq: number;
announcement: MatchedAnnouncement_3;
announcement: MatchedAnnouncement$1;
} | {
chain: 'solana';
timestamp: number;
seq: number;
announcement: MatchedAnnouncement_4;
announcement: MatchedAnnouncement_3;
} | {
chain: 'ckb';
timestamp: number;
Expand Down Expand Up @@ -338,10 +407,10 @@ export interface Schedule {

// @public (undocumented)
export interface SolanaChainInput {
// Warning: (ae-forgotten-export) The symbol "Announcement_3" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Announcement_2" needs to be exported by the entry point index.d.ts
//
// (undocumented)
source: AsyncIterable<Announcement_3>;
source: AsyncIterable<Announcement_2>;
// (undocumented)
spendingPubKey: Uint8Array;
// (undocumented)
Expand All @@ -350,12 +419,36 @@ export interface SolanaChainInput {
viewingKey: Uint8Array;
}

// @public
export type SolanaChainWalletAdapter = BaseWalletAdapter<'solana', Uint8Array>;

// @public
export class SolanaWalletAdapter implements SolanaChainWalletAdapter {
constructor(wallet: SolanaWalletAdapterLike);
// (undocumented)
readonly chain: "solana";
// (undocumented)
getAddress(): Promise<string>;
// (undocumented)
signMessage(message: Uint8Array): Promise<Uint8Array>;
}

// @public
export interface SolanaWalletAdapterLike {
// (undocumented)
publicKey: {
toBase58(): string;
} | null;
// (undocumented)
signMessage?: (message: Uint8Array) => Promise<Uint8Array>;
}

// @public (undocumented)
export interface StellarChainInput {
// Warning: (ae-forgotten-export) The symbol "Announcement_2" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Announcement$1" needs to be exported by the entry point index.d.ts
//
// (undocumented)
source: AsyncIterable<Announcement_2>;
source: AsyncIterable<Announcement$1>;
// (undocumented)
spendingPubKey: Uint8Array;
// (undocumented)
Expand All @@ -364,6 +457,9 @@ export interface StellarChainInput {
viewingKey: Uint8Array;
}

// @public
export type StellarWalletAdapter = BaseWalletAdapter<'stellar', Uint8Array>;

// @public (undocumented)
export type SupportedChain = 'evm' | 'stellar' | 'solana' | 'ckb';

Expand Down Expand Up @@ -392,13 +488,49 @@ export class UnsupportedAssetError extends WraithBuilderError {
readonly code = "WRAITH/BUILDER/UNSUPPORTED_ASSET";
}

// @public
export class ViemWalletAdapter implements EvmWalletAdapter {
constructor(client: ViemWalletClient);
// (undocumented)
readonly chain: "evm";
// (undocumented)
getAddress(): Promise<string>;
// (undocumented)
signMessage(message: Uint8Array): Promise<HexString>;
}

// @public
export interface ViemWalletClient {
// (undocumented)
account?: {
address: string;
} | null;
// (undocumented)
getAddresses?: () => Promise<readonly string[]>;
// (undocumented)
signMessage(args: {
account?: {
address: string;
} | string;
message: {
raw: Uint8Array;
};
}): Promise<HexString>;
}

// @public (undocumented)
export class ViewTagMismatchError extends WraithCryptoError {
constructor(expectedTag: number, actualTag: number);
// (undocumented)
readonly code = "WRAITH/CRYPTO/VIEW_TAG_MISMATCH";
}

// @public
export type WalletAdapter = StellarWalletAdapter | EvmWalletAdapter | SolanaChainWalletAdapter;

// @public
export type WalletAdapterChain = 'stellar' | 'evm' | 'solana';

// @public (undocumented)
export class Wraith {
constructor(config: WraithConfig);
Expand Down Expand Up @@ -504,8 +636,8 @@ export abstract class WraithNetworkError extends WraithError {
// Warnings were encountered during analysis:
//
// dist/index.d.ts:207:5 - (ae-forgotten-export) The symbol "MatchedAnnouncement_2" needs to be exported by the entry point index.d.ts
// dist/index.d.ts:212:5 - (ae-forgotten-export) The symbol "MatchedAnnouncement_3" needs to be exported by the entry point index.d.ts
// dist/index.d.ts:217:5 - (ae-forgotten-export) The symbol "MatchedAnnouncement_4" needs to be exported by the entry point index.d.ts
// dist/index.d.ts:212:5 - (ae-forgotten-export) The symbol "MatchedAnnouncement$1" needs to be exported by the entry point index.d.ts
// dist/index.d.ts:217:5 - (ae-forgotten-export) The symbol "MatchedAnnouncement_3" needs to be exported by the entry point index.d.ts
// dist/index.d.ts:222:5 - (ae-forgotten-export) The symbol "MatchedStealthCell" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)
Expand Down
8 changes: 5 additions & 3 deletions examples/multichain-scan/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Your secret key (64-byte hex string, 128 hex chars)
# Used to derive stealth keys for all chains.
SECRET_KEY="your-64-byte-hex-secret-key-here"
# Module exporting a Map<string, WalletAdapter> named `walletAdapters`.
WALLET_REGISTRY_MODULE="./wallet-registry.ts"

# Optional legacy signature for also scanning Solana and CKB.
SECRET_KEY=""

# Optional: limit scan range (ISO timestamp or empty for full range)
FROM_TIMESTAMP=""
63 changes: 38 additions & 25 deletions examples/multichain-scan/README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
# Multichain Stealth Payment Scanner

A CLI that scans for incoming stealth payments across all 4 supported chains in parallel — Stellar, EVM, Solana, and CKB.

## How it works

1. Derives stealth keys from a single secret key
2. Fetches announcements on all 4 chains simultaneously via `Promise.all`
3. Filters announcements owned by this wallet using each chain's scan function
4. Prints matched payments grouped by chain

## Supported Chains
# Multichain Wallet Scanner

A CLI that uses one `WalletAdapter` registry to request the chain-specific
derivation signatures and scan the Wraith Stellar and Horizen test networks.
An optional legacy signature can also enable the existing Solana and CKB scans.

## Wallet registry

Create `wallet-registry.ts` next to the example. The SDK adapters are structural:
the Freighter, viem, and Solana wallet packages remain optional and are never
imported by the SDK adapters themselves.

```ts
import {
FreighterWalletAdapter,
ViemWalletAdapter,
type WalletAdapter,
} from '@wraith-protocol/sdk';
import { createWalletClient, custom } from 'viem';
import { horizenTestnet } from './your-chain-config';
import * as freighter from '@stellar/freighter-api';

const evmClient = createWalletClient({
chain: horizenTestnet,
transport: custom(window.ethereum),
});

export const walletAdapters = new Map<string, WalletAdapter>([
['stellar', new FreighterWalletAdapter(freighter)],
['evm', new ViemWalletAdapter(evmClient)],
]);
```

| Chain | Fetch function | Scan function | Crypto |
| ------- | -------------------- | ------------------- | --------- |
| Stellar | `fetchAnnouncements` | `scanAnnouncements` | ed25519 |
| EVM | `fetchAnnouncements` | `scanAnnouncements` | secp256k1 |
| Solana | `fetchAnnouncements` | `scanAnnouncements` | ed25519 |
| CKB | `fetchStealthCells` | `scanStealthCells` | secp256k1 |
The same registry can include a `SolanaWalletAdapter` from an
`@solana/wallet-adapter` wallet when a Solana scan is needed.

## Usage

```bash
# 1. Copy and fill in the environment variables
cp .env.example .env
# Edit .env with your SECRET_KEY

# 2. Run the scanner
# Set WALLET_REGISTRY_MODULE to the registry module above.
npm start
```

## Output

The script prints results per chain — total announcements found, matched payments, and details for each match including stealth address, ephemeral public key, and derived private key/scalar.
The CLI asks both wallets to sign their chain's fixed, non-transactional Wraith
message, derives the correct key shape through `deriveStealthKeysFromWallet`,
then scans Stellar testnet and Horizen testnet concurrently.
Loading
Loading