# Yours Wallet Provider API - LLM Reference
## Quick Reference
**Core Object**: `window.yours` (injected by browser extension)
**React Hook**: `useYoursWallet()` from `yours-wallet-provider`
**Installation**: `npm i yours-wallet-provider`
### Essential Methods
```javascript
// Connection
await wallet.connect() → string (identityPubKey)
await wallet.disconnect() → boolean
await wallet.isConnected() → boolean
// Core Data
await wallet.getAddresses() → {bsvAddress, ordAddress, identityAddress}
await wallet.getPubKeys() → {bsvPubKey, ordPubKey, identityPubKey}
await wallet.getBalance() → {bsv, satoshis, usdInCents}
// Transactions
await wallet.sendBsv(SendBsv[]) → {txid, rawtx}
await wallet.sendBsv20(SendBsv20) → {txid, rawtx}
await wallet.transferOrdinal(TransferOrdinal) → txid
```
## Method Summary Table
| Category | Method | Parameters | Returns | Purpose |
|----------|---------|------------|---------|---------|
| **Connection** | `connect()` | none | `string` | Connect wallet, get identity pubkey |
| | `disconnect()` | none | `boolean` | Disconnect wallet |
| | `isConnected()` | none | `boolean` | Check connection status |
| **Wallet Info** | `getAddresses()` | none | `Addresses` | Get BSV/Ord/Identity addresses |
| | `getPubKeys()` | none | `PubKeys` | Get public keys |
| | `getBalance()` | none | `Balance` | Get BSV balance |
| | `getExchangeRate()` | none | `number` | Get BSV/USD rate |
| | `getPaymentUtxos()` | none | `Utxo[]` | Get spendable UTXOs |
| | `getSocialProfile()` | none | `SocialProfile` | Get display name/avatar |
| **Transactions** | `sendBsv()` | `SendBsv[]` | `SendBsvResponse` | Send BSV transactions |
| | `broadcast()` | `Broadcast` | `string` | Broadcast raw transaction |
| **Ordinals** | `inscribe()` | `InscribeRequest[]` | `SendBsvResponse` | Create inscriptions |
| | `getOrdinals()` | `GetPaginatedOrdinals?` | `Ordinal[]` | Get user's ordinals |
| | `transferOrdinal()` | `TransferOrdinal` | `string` | Transfer ordinal |
| | `purchaseOrdinal()` | `PurchaseOrdinal` | `string` | Buy ordinal from marketplace |
| **BSV-20** | `getBsv20s()` | none | `Bsv20[]` | Get BSV-20 tokens |
| | `sendBsv20()` | `SendBsv20` | `SendBsv20Response` | Send BSV-20 tokens |
| | `purchaseBsv20()` | `PurchaseOrdinal` | `string` | Buy BSV-20 from marketplace |
| **MNEE** | `getMNEEBalance()` | none | `MNEEBalance` | Get MNEE balance |
| | `sendMNEE()` | `SendMNEE[]` | `SendMNEEResponse` | Send MNEE stablecoin |
| **Cryptography** | `signMessage()` | `SignMessage` | `SignedMessage` | Sign message |
| | `getSignatures()` | `GetSignatures` | `SignatureResponse[]` | Get tx signatures |
| | `encrypt()` | `EncryptRequest` | `string[]` | Encrypt data |
| | `decrypt()` | `DecryptRequest` | `string[]` | Decrypt data |
| **Advanced** | `generateTaggedKeys()` | `TaggedDerivationRequest` | `TaggedDerivationResponse` | Create tagged key pair |
| | `getTaggedKeys()` | `GetTaggedKeysRequest` | `TaggedDerivationResponse[]` | Get existing tagged keys |
| | `lock()` | `LockRequest[]` | `SendBsvResponse` | Time-lock BSV |
| **Events** | `on()` | `event, listener` | `void` | Add event listener |
| | `removeListener()` | `event, listener` | `void` | Remove event listener |
## Common Workflows
### 1. Basic Wallet Integration
```javascript
// React setup
import { YoursProvider, useYoursWallet } from 'yours-wallet-provider';
// App wrapper
// Component usage
const wallet = useYoursWallet();
// Check if installed
if (!wallet?.isReady) {
window.open("https://yours.org", "_blank");
return;
}
// Connect
const pubKey = await wallet.connect();
// Event listeners (required for good UX)
wallet.on('switchAccount', handleAccountSwitch);
wallet.on('signedOut', () => wallet.disconnect());
```
### 2. Send BSV Transaction
```javascript
const payments = [
{ satoshis: 10000, address: "1ABC..." }, // Simple payment
{ satoshis: 5000, paymail: "user@domain.com" }, // Paymail
{ satoshis: 0, data: ["hello"].map(s => Buffer.from(s).toString('hex')) }, // Data
{ satoshis: 1, script: "76a914...88ac" } // Custom script
];
const { txid, rawtx } = await wallet.sendBsv(payments);
```
### 3. Create Inscription
```javascript
const inscriptions = [{
address: await wallet.getAddresses().ordAddress,
base64Data: btoa("Hello World"),
mimeType: "text/plain",
map: { app: "MyApp", type: "text" },
satoshis: 1
}];
const { txid } = await wallet.inscribe(inscriptions);
```
### 4. Paginated Ordinals Loading
```javascript
let from = undefined;
const allOrdinals = [];
do {
const { ordinals, from: nextFrom } = await wallet.getOrdinals({
from,
limit: 50
});
allOrdinals.push(...ordinals);
from = nextFrom;
} while (from);
```
## Complete Type Definitions
### Core Response Types
```typescript
type Addresses = {
bsvAddress: string; // For BSV transactions
ordAddress: string; // For ordinals/inscriptions
identityAddress: string; // For identity/social features
};
type PubKeys = {
bsvPubKey: string;
ordPubKey: string;
identityPubKey: string;
};
type Balance = {
bsv: number; // BSV amount (decimal)
satoshis: number; // Satoshis (integer)
usdInCents: number; // USD value in cents
};
type MNEEBalance = {
amount: number;
decimalAmount: number;
};
type SocialProfile = {
displayName: string;
avatar: string;
};
type Utxo = {
satoshis: number;
script: string; // hex string
txid: string;
vout: number;
};
```
### Transaction Types
```typescript
type SendBsv = {
address?: string; // Bitcoin address
paymail?: string; // Paymail address
satoshis: number; // Amount in satoshis
data?: string[]; // Hex-encoded data array
script?: string; // Custom output script (hex)
inscription?: RawInscription; // Inscription data
};
type SendBsv20 = {
idOrTick: string; // Token ID or ticker
address: string; // Recipient address
amount: number; // Amount (wallet handles decimals)
};
type SendMNEE = {
address: string;
amount: number;
};
type TransferOrdinal = {
address: string; // Recipient address
origin: string; // Ordinal origin
outpoint: string; // UTXO outpoint
};
type PurchaseOrdinal = {
outpoint: string;
marketplaceRate?: number;
marketplaceAddress?: string;
};
```
### Response Types
```typescript
type SendBsvResponse = {
txid: string;
rawtx: string;
};
type SendBsv20Response = {
txid: string;
rawtx: string;
};
type SendMNEEResponse = {
txid: string;
rawtx: string;
};
type SignedMessage = {
address: string;
pubKey: string;
sig: string;
message: string;
derivationTag: DerivationTag;
};
```
### Ordinals & BSV-20 Types
```typescript
type Ordinal = {
txid: string;
vout: number;
outpoint: string;
satoshis: number;
owner?: string;
script?: string;
spend?: string;
origin?: Origin;
height: number;
idx: number;
data: OrdinalData;
};
type GetPaginatedOrdinals = {
from?: string; // pagination cursor
limit?: number; // default: 50
mimeType?: string; // filter by content type
};
type PaginatedOrdinalsResponse = {
ordinals: Ordinal[];
from?: string; // undefined = no more results
};
type Origin = {
outpoint: string;
nonce?: number;
data?: OrdinalData;
num?: string;
map?: { [key: string]: any };
};
type OrdinalData = {
types?: string[];
insc?: Inscription;
map?: { [key: string]: any };
b?: File;
sigma?: Sigma[];
list?: Listing;
bsv20?: Bsv20;
lock?: Lock;
};
interface Bsv20 {
p: string;
op: string;
dec: number;
amt: string;
all: Bsv20Balance;
listed: Bsv20Balance;
status?: Bsv20Status;
tick?: string;
icon?: string;
id?: string;
sym?: string;
}
interface Bsv20Balance {
confirmed: bigint;
pending: bigint;
}
enum Bsv20Status {
Invalid = -1,
Pending = 0,
Valid = 1,
}
```
### Inscription & Content Types
```typescript
type InscribeRequest = {
address: string; // Where to inscribe
base64Data: string; // Content (base64)
mimeType: MimeTypes; // Content type
map?: MAP; // Metadata
satoshis?: number; // Value (default: 1)
};
type RawInscription = {
base64Data: string;
mimeType: MimeTypes;
map?: MAP;
};
type MAP = {
app: string;
type: string;
[prop: string]: string
};
type MimeTypes =
| "text/plain" | "text/html" | "text/css"
| "application/javascript" | "application/json" | "application/xml"
| "image/jpeg" | "image/png" | "image/gif" | "image/svg+xml"
| "audio/mpeg" | "audio/wav" | "audio/wave"
| "video/mp4"
| "application/pdf" | "application/msword"
| "application/vnd.ms-excel" | "application/vnd.ms-powerpoint"
| "application/zip" | "application/x-7z-compressed"
| "application/x-gzip" | "application/x-tar" | "application/x-bzip2";
type File = {
type: string;
size: number;
hash: string;
text?: string;
json?: { [key: string]: any };
};
type Inscription = {
file: File;
fields?: { [key: string]: any };
parent?: string;
};
```
### Cryptography & Signing Types
```typescript
type SignMessage = {
message: string;
encoding?: "utf8" | "hex" | "base64";
tag?: DerivationTag;
};
type SignatureRequest = {
prevTxid: string;
outputIndex: number;
inputIndex: number; // Input index to sign
satoshis: number; // Previous output value
address: string | string[]; // Required signing address(es)
script?: string; // Previous output script (hex)
sigHashType?: number; // Default: SIGHASH_ALL | SIGHASH_FORKID
csIdx?: number; // OP_CODESEPARATOR index
data?: unknown; // Extra signing data
};
type SignatureResponse = {
inputIndex: number;
sig: string; // Signature
pubKey: string; // Public key
sigHashType: number;
csIdx?: number;
};
type GetSignatures = {
rawtx: string;
sigRequests: SignatureRequest[];
format?: TransactionFormat;
};
type EncryptRequest = {
message: string;
pubKeys: string[];
encoding?: "utf8" | "hex" | "base64";
tag?: DerivationTag;
};
type DecryptRequest = {
messages: string[]; // base64 encrypted strings
tag?: DerivationTag;
};
```
### Tagged Derivation & Utility Types
```typescript
type DerivationTag = {
label: string; // Human-readable tag
id: string; // Unique identifier
domain: string; // Requesting domain
meta?: { [key: string]: any }; // Additional metadata
};
type TaggedDerivationRequest = {
label: string;
id: string;
meta?: { [key: string]: any };
};
type TaggedDerivationResponse = {
address: string;
pubKey: string;
tag: DerivationTag;
};
type GetTaggedKeysRequest = {
label: string;
ids?: string[]; // Filter by specific IDs
};
type LockRequest = {
address: string; // Where to lock (recommend identity)
blockHeight: number; // Unlock block height
sats: number; // Satoshis to lock
};
type Broadcast = {
rawtx: string;
format?: TransactionFormat; // "tx" | "beef" | "ef"
fund?: boolean;
};
type TransactionFormat = "tx" | "beef" | "ef";
enum NetWork {
Mainnet = "mainnet",
Testnet = "testnet",
}
```
### Event Types
```typescript
type YoursEvents = "signedOut" | "switchAccount";
type YoursEventListeners = (args?: { [key: string]: any }) => void;
```
### Main Provider Interface
```typescript
type YoursProviderType = {
isReady: boolean;
on: (event: YoursEvents, listener: YoursEventListeners) => void;
removeListener: (event: YoursEvents, listener: YoursEventListeners) => void;
connect: () => Promise;
disconnect: () => Promise;
isConnected: () => Promise;
getPubKeys: () => Promise;
getAddresses: () => Promise;
getNetwork: () => Promise;
getSocialProfile: () => Promise;
getBalance: () => Promise;
getMNEEBalance: () => Promise;
getOrdinals: (params?: GetPaginatedOrdinals) => Promise;
getBsv20s: () => Promise;
sendBsv: (params: SendBsv[]) => Promise;
sendBsv20: (params: SendBsv20) => Promise;
sendMNEE: (params: SendMNEE[]) => Promise;
transferOrdinal: (params: TransferOrdinal) => Promise;
purchaseOrdinal: (params: PurchaseOrdinal) => Promise;
purchaseBsv20: (params: PurchaseOrdinal) => Promise;
signMessage: (params: SignMessage) => Promise;
getSignatures: (params: GetSignatures) => Promise;
broadcast: (params: Broadcast) => Promise;
getExchangeRate: () => Promise;
getPaymentUtxos: () => Promise;
generateTaggedKeys: (params: TaggedDerivationRequest) => Promise;
getTaggedKeys: (params: GetTaggedKeysRequest) => Promise;
inscribe: (params: InscribeRequest[]) => Promise;
lock: (params: LockRequest[]) => Promise;
encrypt: (params: EncryptRequest) => Promise;
decrypt: (params: DecryptRequest) => Promise;
};
```
## Error Handling Patterns
### Standard Error Handling
```javascript
try {
const result = await wallet.someMethod(params);
return result;
} catch (error) {
if (error.message?.includes('User denied')) {
// User rejected the request
console.log('User cancelled transaction');
} else if (error.message?.includes('Insufficient')) {
// Not enough balance
console.log('Insufficient funds');
} else {
// Other errors
console.error('Wallet error:', error);
}
throw error;
}
```
### Connection State Checking
```javascript
const ensureConnected = async () => {
if (!wallet?.isReady) {
throw new Error('Wallet not installed');
}
if (!await wallet.isConnected()) {
await wallet.connect();
}
};
```
## Security Considerations
- **Auto-disconnect**: Wallet disconnects after 10 minutes of inactivity
- **Domain whitelisting**: Successful connections whitelist your domain
- **User approval**: All transactions require user confirmation
- **Key isolation**: Tagged derivation keys are domain-specific
- **Encryption**: Uses identity keys for encrypt/decrypt operations
## Troubleshooting
### Common Issues
**Wallet not detected**
```javascript
// Check installation
if (typeof window === 'undefined' || !window.yours) {
// Redirect to installation
window.open("https://yours.org", "_blank");
}
```
**Connection failures**
```javascript
// Ensure proper event handling
useEffect(() => {
if (!wallet?.on) return;
const handleSignOut = () => {
wallet.disconnect();
// Update your app state
};
wallet.on('signedOut', handleSignOut);
return () => wallet.removeListener('signedOut', handleSignOut);
}, [wallet]);
```
**TypeScript errors**
```typescript
// Add to global.d.ts
declare global {
interface Window {
yours: YoursProviderType;
}
}
```
**Transaction failures**
- Check balance before sending
- Validate addresses/paymails
- Ensure proper data encoding (hex for data arrays)
- Verify UTXO availability for ordinal transfers
### Best Practices
1. **Always implement event listeners** for `switchAccount` and `signedOut`
2. **Check wallet readiness** before attempting connections
3. **Handle user rejections gracefully**
4. **Use pagination** for ordinals in wallets with many NFTs
5. **Cache exchange rates** (they're cached for 5 minutes server-side)
6. **Validate inputs** before sending to wallet methods
7. **Use identity address** for locking BSV
## Integration Examples
### Minimal Integration
```javascript
// Vanilla JS
if (window.yours) {
const pubKey = await window.yours.connect();
const { bsvAddress } = await window.yours.getAddresses();
console.log('Connected:', bsvAddress);
}
```
### React Hook Pattern
```javascript
const useWalletConnection = () => {
const wallet = useYoursWallet();
const [isConnected, setIsConnected] = useState(false);
useEffect(() => {
if (!wallet) return;
const checkConnection = async () => {
setIsConnected(await wallet.isConnected());
};
checkConnection();
wallet.on('signedOut', () => setIsConnected(false));
wallet.on('switchAccount', checkConnection);
return () => {
wallet.removeListener('signedOut', () => setIsConnected(false));
wallet.removeListener('switchAccount', checkConnection);
};
}, [wallet]);
return { wallet, isConnected };
};
```
### Marketplace Integration
```javascript
// Buy ordinal from marketplace
const purchaseOrdinal = async (outpoint, marketplaceAddress) => {
try {
const txid = await wallet.purchaseOrdinal({
outpoint,
marketplaceRate: 0.05, // 5% marketplace fee
marketplaceAddress
});
console.log('Purchase successful:', txid);
} catch (error) {
console.error('Purchase failed:', error);
}
};
```