| name | payments |
| description | This skill should be used when sending BSV with the 1sat-sdk — single payments, batch payments to multiple recipients, paymail sends, OP_RETURN data, custom locking scripts, inscriptions attached to a payment, sweeping a wallet's whole balance to one destination, or deriving deposit addresses to receive BSV. Triggers on 'send BSV', 'payment', 'batch payment', 'pay to paymail', 'OP_RETURN', 'send all BSV', 'sweep balance', 'deposit address', 'receive BSV', or 'derive address'. Uses @1sat/actions. |
Payments
Send BSV and derive deposit addresses with @1sat/actions.
Calling Pattern
import { createContext, sendBsv } from '@1sat/actions'
const ctx = createContext(wallet, { services })
const result = await sendBsv.execute(ctx, input)
services is optional for these actions but provide it if you have it. The wallet is any BRC-100 compatible WalletInterface.
sendBsv
Send BSV to one or more destinations in a single transaction. Single-phase — it calls wallet.createAction directly and does not use two-phase signing. Plain sends carry no P1Sat semantics (no asset inputs, no basketed outputs).
Input
interface SendBsvInput {
requests: SendBsvRequest[]
fundingProvider?: FundingProvider
}
interface SendBsvRequest {
address?: string
paymail?: string
satoshis: number
script?: string
data?: string[]
inscription?: {
base64Data: string
mimeType: string
map?: Record<string, string>
}
fundingProvider?: FundingProvider
}
Each request resolves to exactly one output, chosen by which field is set (precedence): paymail → script → address (with optional inscription) → data (OP_RETURN). A request with none of these returns { error: 'invalid-request' }.
Response
interface SendBsvResponse {
txid?: string
tx?: number[]
error?: string
}
Examples
await sendBsv.execute(ctx, {
requests: [{ address: '1Recipient...', satoshis: 50000 }],
})
await sendBsv.execute(ctx, {
requests: [
{ address: '1Alice...', satoshis: 10000 },
{ address: '1Bob...', satoshis: 20000 },
],
})
await sendBsv.execute(ctx, {
requests: [{ paymail: 'alice@example.com', satoshis: 25000 }],
})
await sendBsv.execute(ctx, {
requests: [{ script: '76a914...88ac', satoshis: 5000 }],
})
await sendBsv.execute(ctx, {
requests: [{ data: ['hello', 'world'], satoshis: 0 }],
})
await sendBsv.execute(ctx, {
requests: [{
address: '1Recipient...',
satoshis: 1,
inscription: {
base64Data: btoa('Hello on-chain'),
mimeType: 'text/plain',
},
}],
})
Notes
- Paymail sends call
getP2pPaymentDestination to fetch the recipient's outputs and a reference, then deliver the transaction BEEF P2P (sendBeefP2P) after broadcast. The AtomicBEEF returned by createAction is converted to plain BEEF (BRC-62) before delivery.
- fundingProvider: when set, the provider funds and broadcasts the transaction instead of the wallet. Can be passed at the input level or per-request.
- Returns
{ error: 'no-requests' } for an empty requests array, { error: 'invalid-data' } for malformed OP_RETURN data, and { error: 'no-txid-returned' } if the wallet returns no txid.
sendAllBsv
Sweep the wallet's entire spendable balance to a single destination address. Single-phase like sendBsv. Uses the wallet's max-fundable sentinel so the output is adjusted to all available funds minus fees.
Input
interface SendAllBsvInput {
destination: string
fundingProvider?: FundingProvider
}
Returns SendBsvResponse. Paymail destinations are rejected — use sendBsv with a fixed amount instead.
import { createContext, sendAllBsv } from '@1sat/actions'
const ctx = createContext(wallet, { services })
await sendAllBsv.execute(ctx, { destination: '1Recipient...' })
deriveDepositAddresses
Derive P1SAT wallet-bound deposit addresses from the wallet's identity key, for receiving BSV (or ordinals/tokens). KeyID format is <prefix> <index> (plaintext). This is a read-only derivation — it does not build a transaction.
Input
interface DeriveDepositAddressesInput {
prefix?: string
startIndex?: number
count?: number
}
The default prefix "1sat" is chosen so any wallet binding the same identity key (yours-wallet, wallet-desktop, CLI, MCP server) derives the same default deposit addresses without coordination. Supply a custom prefix only when you want a distinct address set (e.g. "mcp").
Result
interface DeriveDepositAddressesResult {
derivations: AddressDerivation[]
}
interface AddressDerivation {
address: string
index: number
derivationPrefix: string
derivationSuffix: string
senderIdentityKey: string
publicKey: string
}
import { createContext, deriveDepositAddresses } from '@1sat/actions'
const ctx = createContext(wallet, { services })
const { derivations } = await deriveDepositAddresses.execute(ctx, {})
const { derivations: mcpAddrs } = await deriveDepositAddresses.execute(ctx, {
prefix: 'mcp',
startIndex: 0,
count: 5,
})
Related
- Action/context pattern, two-phase signing, registry, baskets and tags: see ../action-patterns
- Inscriptions as standalone outputs: see ../inscriptions
Requirements
bun add @1sat/actions @bsv/sdk