Non-Custodial Wallet Condensed Flow
Create complete transactions to self-hosted (non-custodial) wallets with automatic KYC screening and workflow optimization in a single API call.
Use Case
Perfect for transactions where the beneficiary wallet is self-hosted by an individual rather than managed by a VASP. The system automatically handles the simplified workflow required for non-custodial recipients.
Key Features
- No VASP Required: Beneficiary manages their own wallet
- Simplified Workflow: Automatic skip of beneficiary VASP communication
- Enhanced KYC: Additional screening for self-custody scenarios
- Compliance Maintained: Full Travel Rule compliance despite non-custodial nature
Request
Endpoint: POST https://api.trpcontinuum.com/trp/transactions/condensed
Headers:
Content-Type: application/json
Authorization: Bearer {your-token}
Request Body:
{
"transaction": {
"network": "bitcoin",
"virtualAsset": "Bitcoin (BTC)",
"amount": "50.25",
"beneficiaryWalletAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"originatorWalletAddress": "bc1qabc123def456ghi789jkl012mno345pqr678stu",
"memo": "Payment to non-custodial wallet"
},
"beneficiary": {
"isNonCustodialWallet": true,
"beneficiaryIsLegalPerson": false,
"beneficiaryFirstName": "Jane",
"beneficiaryLastName": "Smith",
"dateOfBirth": "1992-07-15",
"placeOfBirth": "Boston, MA",
"beneficiaryIdNumber": "555666777",
"beneficiaryIdType": "PASSPORT",
"beneficiaryIdCountryOfIssue": "US",
"buildingNumber": "789",
"streetName": "Crypto Street",
"townName": "Boston",
"postCode": "02101",
"country": "US"
},
"originator": {
"originatorIsLegalPerson": false,
"originatorFirstName": "John",
"originatorLastName": "Doe",
"originatorDob": "1985-03-20",
"originatorPlaceOfBirth": "Chicago, IL",
"originatorIdNumber": "987654321",
"originatorIdType": "PASSPORT",
"originatorIdCountryOfIssue": "US",
"originatorAddressLine1": "456 Oak Street",
"originatorAddressLine2": "Apt 3A",
"originatorCity": "San Francisco",
"originatorState": "CA",
"originatorPostalCode": "94102",
"originatorCountry": "US"
}
}
Response Examples
Success (No KYC Matches)
{
"success": true,
"data": {
"id": "txn_noncust123",
"status": "Waiting for TX Hash",
"network": "bitcoin",
"virtualAsset": "Bitcoin (BTC)",
"amount": "50.25",
"beneficiaryWalletAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"originatorWalletAddress": "bc1qabc123def456ghi789jkl012mno345pqr678stu",
"beneficiary": {
"beneficiaryFirstName": "Jane",
"beneficiaryLastName": "Smith",
"isNonCustodialWallet": true,
"beneficiaryVaspName": "NON-CUSTODIAL-WALLET"
},
"originator": {
"originatorFirstName": "John",
"originatorLastName": "Doe"
},
"kycCheck": {
"hasMatches": false,
"totalMatches": 0,
"beneficiaryChecked": true,
"originatorChecked": true,
"nonCustodialScreening": true,
"screenedAt": "2024-08-07T10:00:00Z"
},
"workflowType": "non_custodial",
"autoSkippedSteps": [
"send_to_beneficiary_vasp",
"approve_originator",
"payment_check"
],
"createdAt": "2024-08-07T10:00:00Z",
"updatedAt": "2024-08-07T10:00:00Z"
}
}
Success (KYC Matches Found)
{
"success": true,
"data": {
"id": "txn_noncust456",
"status": "KYC Beneficiary Pending Review",
"network": "bitcoin",
"virtualAsset": "Bitcoin (BTC)",
"amount": "50.25",
"kycCheck": {
"hasMatches": true,
"totalMatches": 1,
"beneficiaryMatches": 1,
"originatorMatches": 0,
"topMatch": {
"score": 0.87,
"name": "Jane Smith",
"riskLevel": "high",
"sources": ["watchlist"],
"details": {
"birthDate": "1992-07-15",
"country": "US",
"matchType": "name_dob_country",
"walletType": "non_custodial"
}
},
"nonCustodialScreening": true,
"enhancedScreening": {
"walletAnalysis": true,
"addressRiskScore": 0.1,
"previousTransactions": 0
},
"screenedAt": "2024-08-07T10:00:00Z"
},
"workflowType": "non_custodial",
"createdAt": "2024-08-07T10:00:00Z",
"updatedAt": "2024-08-07T10:00:00Z"
}
}
Required Fields
Transaction
network- Blockchain networkvirtualAsset- Asset nameamount- Transaction amount as stringbeneficiaryWalletAddress- Self-hosted wallet addressoriginatorWalletAddress- Sender wallet address
Beneficiary (Non-Custodial)
isNonCustodialWallet- Must betruebeneficiaryIsLegalPerson- Usuallyfalse(individuals)beneficiaryFirstName- First name (if natural person)beneficiaryLastName- Last name (if natural person)dateOfBirth- Birth date (YYYY-MM-DD format)country- Country code (ISO 3166-1 alpha-2)
Originator
originatorIsLegalPerson-trueorfalseoriginatorFirstName/originatorLastName(if natural person)originatorLegalName(if legal person)originatorDob(natural person) /originatorDateOfIncorporation(legal person)originatorCountry- Country code
Optional Fields
Enhanced Beneficiary Data
beneficiaryIdNumber- ID document numberbeneficiaryIdType- ID type ("PASSPORT", "NATIONAL_ID", "DRIVERS_LICENSE")beneficiaryIdCountryOfIssue- Issuing countryplaceOfBirth- Place of birth- Address fields:
buildingNumber,streetName,townName,postCode
Wallet Information
walletProvider- Wallet software/provider (if known)walletType- Type of non-custodial walletselfCustodyConfirmation- Confirmation that wallet is self-hosted
Non-Custodial Workflow
Automatic Skip Steps
When isNonCustodialWallet: true, the system automatically:
- Skips Beneficiary VASP Communication - No VASP to notify
- Skips Originator Approval - No beneficiary VASP to approve
- Skips Payment Check - No VASP payment verification needed
- Direct to TX Hash - Ready for blockchain transaction
Status Progression (No KYC Matches)
Waiting for TX Hash- Ready for blockchain transaction- Submit TX hash via
/tx-hash-submitendpoint Tx Hash Sent Successfully- Transaction complete
Status Progression (With KYC Matches)
KYC Beneficiary Pending Review- Manual review required- After KYC approval →
Waiting for TX Hash - Submit TX hash →
Tx Hash Sent Successfully
Enhanced KYC for Non-Custodial
Additional Screening
Non-custodial transactions receive enhanced screening:
- Wallet Address Analysis: Risk scoring of destination address
- Blockchain Analysis: Previous transaction history review
- Enhanced Entity Screening: Additional focus on self-custody risks
- Geographic Risk Assessment: Country-specific non-custodial regulations
Risk Factors
Higher scrutiny applied for:
- Large amounts to non-custodial wallets
- First-time recipients
- High-risk jurisdictions
- Privacy coins or mixers
- Suspicious address patterns
Code Examples
JavaScript/Node.js
const axios = require('axios');
async function createNonCustodialTransaction() {
try {
const response = await axios.post('https://api.trpcontinuum.com/trp/transactions/condensed', {
transaction: {
network: "bitcoin",
virtualAsset: "Bitcoin (BTC)",
amount: "25.50",
beneficiaryWalletAddress: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
originatorWalletAddress: "bc1qabc123def456ghi789jkl012mno345pqr678stu",
memo: "Payment to personal wallet"
},
beneficiary: {
isNonCustodialWallet: true,
beneficiaryIsLegalPerson: false,
beneficiaryFirstName: "Alice",
beneficiaryLastName: "Johnson",
dateOfBirth: "1988-11-22",
country: "US",
beneficiaryIdNumber: "123987456",
beneficiaryIdType: "PASSPORT",
walletProvider: "Electrum"
},
originator: {
originatorIsLegalPerson: false,
originatorFirstName: "Bob",
originatorLastName: "Wilson",
originatorDob: "1985-03-20",
originatorCountry: "US"
}
}, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (response.data.success) {
const transaction = response.data.data;
if (transaction.kycCheck.hasMatches) {
console.log(`Non-custodial transaction ${transaction.id} held for review`);
console.log(`Enhanced screening flagged ${transaction.kycCheck.totalMatches} matches`);
// Handle KYC review
} else {
console.log(`Non-custodial transaction ${transaction.id} ready for blockchain execution`);
console.log(`Status: ${transaction.status}`);
console.log(`Skipped steps: ${transaction.autoSkippedSteps.join(', ')}`);
// Proceed directly to blockchain transaction
// await executeBlockchainTransaction(transaction);
}
}
} catch (error) {
console.error('Non-custodial transaction failed:', error.response?.data);
}
}
async function submitTransactionHash(transactionId, txHash) {
try {
const response = await axios.post(`https://api.trpcontinuum.com/trp/transactions/${transactionId}/tx-hash-submit`, {
txHash: txHash,
note: "Transaction broadcast to Bitcoin network"
}, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (response.data.success) {
console.log(`Transaction ${transactionId} completed successfully`);
console.log(`TX Hash: ${txHash}`);
}
} catch (error) {
console.error('TX hash submission failed:', error.response?.data);
}
}
Python
import requests
import hashlib
def create_non_custodial_transaction():
payload = {
"transaction": {
"network": "bitcoin",
"virtualAsset": "Bitcoin (BTC)",
"amount": "25.50",
"beneficiaryWalletAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"originatorWalletAddress": "bc1qabc123def456ghi789jkl012mno345pqr678stu",
"memo": "Payment to personal wallet"
},
"beneficiary": {
"isNonCustodialWallet": True,
"beneficiaryIsLegalPerson": False,
"beneficiaryFirstName": "Alice",
"beneficiaryLastName": "Johnson",
"dateOfBirth": "1988-11-22",
"country": "US",
"beneficiaryIdNumber": "123987456",
"beneficiaryIdType": "PASSPORT",
"walletProvider": "Electrum"
},
"originator": {
"originatorIsLegalPerson": False,
"originatorFirstName": "Bob",
"originatorLastName": "Wilson",
"originatorDob": "1985-03-20",
"originatorCountry": "US"
}
}
response = requests.post(
'https://api.trpcontinuum.com/trp/transactions/condensed',
json=payload,
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
if response.status_code == 200:
data = response.json()
if data['success']:
transaction = data['data']
print(f"Non-custodial transaction created: {transaction['id']}")
print(f"Workflow type: {transaction['workflowType']}")
print(f"Status: {transaction['status']}")
if transaction['kycCheck']['hasMatches']:
print("⚠️ KYC review required")
handle_kyc_review(transaction['id'])
else:
print("✅ Ready for blockchain execution")
print(f"Auto-skipped: {', '.join(transaction['autoSkippedSteps'])}")
# Simulate blockchain transaction
tx_hash = simulate_blockchain_transaction(transaction)
submit_transaction_hash(transaction['id'], tx_hash)
else:
print(f"Error: {response.status_code} - {response.text}")
def simulate_blockchain_transaction(transaction):
# In real implementation, this would broadcast to blockchain
import uuid
return f"0x{uuid.uuid4().hex}"
def submit_transaction_hash(transaction_id, tx_hash):
response = requests.post(
f'https://api.trpcontinuum.com/trp/transactions/{transaction_id}/tx-hash-submit',
json={
'txHash': tx_hash,
'note': 'Non-custodial transaction completed'
},
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
if response.status_code == 200:
print(f"✅ Transaction completed with hash: {tx_hash}")
else:
print(f"❌ TX hash submission failed: {response.text}")
Next Steps
After Successful Creation (No KYC Matches)
- Execute Blockchain Transaction: Send actual cryptocurrency
- Submit TX Hash: Use
/tx-hash-submitendpoint - Transaction Complete: Status becomes
Tx Hash Sent Successfully
After KYC Approval
- Status Updates:
KYC Beneficiary Pending Review→Waiting for TX Hash - Execute Blockchain Transaction: Proceed with crypto transfer
- Submit TX Hash: Complete the transaction record
Compliance Considerations
Travel Rule Compliance
Even with non-custodial recipients:
- Full originator information collected
- Beneficiary information verified
- Transaction records maintained
- Regulatory reporting requirements met
Enhanced Monitoring
- Higher scrutiny for large amounts
- Blockchain analysis for suspicious patterns
- Geographic risk assessment
- Ongoing transaction monitoring
Regulatory Variations
Different jurisdictions may have specific requirements:
- US: FinCEN guidance on self-hosted wallets
- EU: 5AMLD requirements for crypto-to-crypto transfers
- Japan: JVCEA self-custody reporting requirements
Common Errors
Missing Non-Custodial Flag
{
"success": false,
"error": "MISSING_BENEFICIARY_TYPE",
"message": "Must specify beneficiary type",
"details": {
"required_fields": ["beneficiaryVaspId", "isNonCustodialWallet", "unregisteredVaspWebsite"],
"suggestion": "Set isNonCustodialWallet: true for self-hosted wallets"
}
}
Invalid Wallet Address
{
"success": false,
"error": "INVALID_WALLET_ADDRESS",
"message": "Wallet address format invalid for specified network",
"details": {
"network": "bitcoin",
"address": "0x1234...",
"expectedFormat": "bc1... (Bech32) or 1... (P2PKH) or 3... (P2SH)"
}
}
Testing
Test Scenarios
Low Risk Non-Custodial:
{
"beneficiaryFirstName": "Test",
"beneficiaryLastName": "User",
"dateOfBirth": "1990-01-01",
"isNonCustodialWallet": true
}
High Risk (Will Trigger Review):
{
"beneficiaryFirstName": "High",
"beneficiaryLastName": "Risk",
"dateOfBirth": "1980-01-01",
"country": "IR",
"isNonCustodialWallet": true
}
Wallet Address Testing
Use valid test addresses for different networks:
- Bitcoin:
bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh - Ethereum:
0x742C4B4f7c1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e - Polygon: Same as Ethereum format