<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CryptoSwift</title>
	<atom:link href="https://cryptoswift.eu/feed/" rel="self" type="application/rss+xml" />
	<link>https://cryptoswift.eu/</link>
	<description>End-to-end Crypto Travel Rule Compliance Solution</description>
	<lastBuildDate>Wed, 01 Jul 2026 15:07:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://cryptoswift.eu/wp-content/uploads/2025/02/Favicon-1-150x150.png</url>
	<title>CryptoSwift</title>
	<link>https://cryptoswift.eu/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Navigating the European Dual-Licensing Regime: A Conversation with Januar and CryptoSwift</title>
		<link>https://cryptoswift.eu/navigating-the-european-dual-licensing-regime-a-conversation-with-januar-and-cryptoswift/</link>
		
		<dc:creator><![CDATA[Uve Poom]]></dc:creator>
		<pubDate>Wed, 01 Jul 2026 12:47:52 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=6984</guid>

					<description><![CDATA[<p>The regulatory landscape for stablecoins and e-money tokens (EMTs) in Europe has shifted dramatically. Under recent European Banking Authority (EBA) guidance, crypto-asset service providers (CASPs) face a complex crossover between MiCA frameworks and traditional payment service mandates. In this fireside interview on 16 June 2026 titled &#8220;How can CASPs support stablecoins in 2026?&#8221;, Marcus Mølleskov, [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/navigating-the-european-dual-licensing-regime-a-conversation-with-januar-and-cryptoswift/" data-wpel-link="internal">Navigating the European Dual-Licensing Regime: A Conversation with Januar and CryptoSwift</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h1 id="h-" class="wp-block-heading"></h1>



<p class="wp-block-paragraph">The regulatory landscape for stablecoins and e-money tokens (EMTs) in Europe has shifted dramatically. Under recent European Banking Authority (EBA) guidance, crypto-asset service providers (CASPs) face a complex crossover between MiCA frameworks and traditional payment service mandates.</p>



<p class="wp-block-paragraph">In this fireside interview on <a href="https://event.demio.com/jump/APu0c58MJmHsMHJe" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">16 June 2026 titled <em>&#8220;How can CASPs support stablecoins in 2026?&#8221;</em><span class="wpel-icon wpel-image wpel-icon-19"></span></a>, <strong>Marcus Mølleskov</strong>, Chief Risk and Compliance Officer at <a href="https://januar.com/" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right"><strong>Januar</strong><span class="wpel-icon wpel-image wpel-icon-19"></span></a>, and <strong><a href="https://www.linkedin.com/in/uvepoom/" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">Uve Poom<span class="wpel-icon wpel-image wpel-icon-19"></span></a></strong>, Chief Operating Officer at <strong>CryptoSwift</strong>, break down the operational realities of the dual-licensing regime, the future impact of PSD3/PSR, and how platforms can maintain compliant transactional infrastructure.</p>



<h3 id="h-defining-the-dual-licensing-perimeter" class="wp-block-heading">Defining the Dual-Licensing Perimeter</h3>



<p class="wp-block-paragraph"><strong>Uve Poom (UP):</strong> Let’s dive right into the core issue surrounding the dual-licensing regime. How did this framework come to be, and what is the current sentiment you are picking up in the market, Marcus?</p>



<p class="wp-block-paragraph"><strong>Marcus Mølleskov (MM):</strong> It stems directly from the underlying text of MiCA. The EBA issued a guidance letter clarifying that MiCA equates fiat-pegged e-money tokens to traditional &#8220;funds.&#8221; Consequently, any commercial transaction executed using an EMT is legally classified as a payment transaction, rendering it subject to payment service licensing.</p>



<p class="wp-block-paragraph">The EBA noted that this structural requirement was largely an unexpected outcome of the legislative drafting. They explicitly signaled to the European Commission that this overlap should be remediated in upcoming legislative updates, such as the Third Payment Services Directive (PSD3) or MiCA 2. Because the current statutory text binds their hands, regulators must enforce a dual payment and crypto license if a CASP offers stablecoin custody and transfer capabilities.</p>



<p class="wp-block-paragraph"><strong>UP</strong>: The challenge arises because while a completely closed-loop trading environment would sit safely outside that perimeter, exchanges are legally mandated to allow users to withdraw their digital assets. That withdrawal mechanism effectively triggers a payment transmission.</p>



<p class="wp-block-paragraph"><strong>MM:</strong> Exactly. Under the current enforcement framework, if you provide stablecoin custody, maintain client token balances, or permit user deposits and withdrawals, your infrastructure is legally categorized as a payment account.</p>



<p class="wp-block-paragraph">This interpretation extends to first-party transfers. If an over-the-counter (OTC) broker accepts stablecoin deposits to pre-fund a trading account, that routing layer is treated as a payment service. Regulators have been very clear: platforms with a pending payment license application may continue servicing existing EMT users under strict marketing caps, but those without active applications or authorized third-party partnerships must remove stablecoins from their product offerings entirely.</p>



<h3 id="h-the-impact-of-psd3-and-consolidation" class="wp-block-heading">The Impact of PSD3 and Consolidation</h3>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> Looking at the broader European market, we are seeing a contraction from thousands of legacy virtual asset firms down to a leaner group of authorized CASPs. How many of these remaining entities are actively seeking dual payment permissions versus utilizing third-party partnerships?</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> The EBA indicated they were tracking more than 100 parallel payment institution applications submitted by entities traversing the MiCA pipeline. However, the operational reality caught many market participants by surprise. Multiple national regulators informed applicants that they lacked the internal administrative capacity to evaluate both a CASP and a payment service license application concurrently ahead of statutory deadlines.</p>



<p class="wp-block-paragraph">To preserve their stablecoin features, these platforms were directed to secure an authorized partner. At Januar, we established a compliant subcustodial proof-of-concept that satisfied regulatory scrutiny, allowing CASPs to proceed to the final stages of authorization. The fact that prominent platforms are still scrambling to resolve this architecture demonstrates that the industry was not fully prepared for the enforcement timelines.</p>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> We observe a matching trend within the Travel Rule and digital asset taxation spaces. The Transfer of Funds Regulation (TFR) demands complete counterparty data for both payers and payees, yet significant compliance debt remains due to systemic friction and low interoperability between various technology vendors.</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> The market is undergoing massive consolidation. Shifting from thousands of unregistered venues to a tightly regulated perimeter means market share is being heavily redistributed. Compliant CASPs are absorbing significant transactional volumes from regional competitors that failed to clear the licensing hurdle. This volume concentration will only intensify as strict reverse-solicitation rules restrict non-EU firms from targeting European enterprises.</p>



<h3 id="h-designing-the-subcustodial-partnership-model" class="wp-block-heading">Designing the Subcustodial Partnership Model</h3>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> Given that your infrastructure services these digital asset exchanges, how does Januar structure its compliance architecture to facilitate third-party payments safely?</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong></strong> Januar was founded to resolve the systemic debanking issues plaguing the crypto sector by providing secure operational accounts and client Euro settlement via named IBANs. Regarding stablecoins, MiCA explicitly permits an authorized CASP to provide payment services in relation to its core activities, provided it routes those flows through a licensed third-party financial institution.</p>



<p class="wp-block-paragraph">This is where Januar steps in as an institutional subcustodian. Under this framework, the CASP does not become our direct payment agent, and Januar does not directly onboard or perform Know Your Customer (KYC) checks on the exchange’s retail end-users. The CASP leverages our regulated payment infrastructure to custody and transmit their underlying stablecoins. It functions exactly like a traditional banking relationship: just as a commercial bank account sits beneath your fiat operations, Januar acts as the compliant financial rail sitting beneath your stablecoin architecture.</p>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> How does Januar manage its compliance exposure under an indirect subcustodial arrangement?</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong></strong>: Our monitoring is focused at the institutional level. We evaluate the corporate activity, operational profiles, and aggregate volume movements of the CASP as a corporate entity. The client CASP retains full, direct responsibility for the onboarding, transaction monitoring, and Travel Rule compliance of their respective end-users. We mitigate our exposure by executing comprehensive due diligence on the CASP’s internal AML policies and control systems before granting access to our rails.</p>



<h3 id="h-build-partner-or-pivot" class="wp-block-heading">Build, Partner, or Pivot</h3>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> To summarize the landscape, a CASP wanting to support stablecoin payments can choose between three strategic options: building an independent payment institution stack, partnering with an authorized provider like Januar, or shifting entirely to non-custodial wallet infrastructure.</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> The boundaries of that third option require careful examination. Regulators prioritize economic substance over technical descriptions. If an exchange provides a &#8220;self-custodial&#8221; wallet that users can only access or interact with through that specific platform&#8217;s interface, authorities will legally designate it as a custodial account and demand a dual license.</p>



<p class="wp-block-paragraph">A legitimate non-custodial model means the CASP&#8217;s architecture must interact directly with user-controlled environments—such as a hardware wallet or MetaMask via smart contracts—where the underlying tokens never touch a corporate corporate wallet address. That represents a fundamental product pivot, turning a centralized venue into a decentralized protocol layer.</p>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> What criteria should a corporate compliance team use to decide whether to build their own payment institution capability or leverage an external partner?</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> If your multi-year product roadmap relies on launching native, heavy consumer payment utilities—such as merchant acquiring infrastructure—investing the capital to build an independent payment institution stack under the upcoming PSD3 and Payment Services Regulation (PSR) makes sense.</p>



<p class="wp-block-paragraph">However, if your primary business model is operating a trading venue or an OTC desk, building an entirely separate financial institution right before PSD3 updates the rules is highly inefficient. The final draft of PSD3 explicitly outlines an exemption for stablecoin transactions used strictly to pre-fund or settle asset trades, which will ultimately reduce the number of firms requiring dual authorization. Partnering allows you to deploy immediately. Even as an established payment provider already vetted by national competent authorities, our own MiCA application required over 1,500 pages of distinct documentation. The regulatory friction of maintaining dual independent licenses is substantial.</p>



<h3 id="h-interoperability-and-the-future-of-verification" class="wp-block-heading">Interoperability and the Future of Verification</h3>



<p class="wp-block-paragraph"><strong><strong>UP</strong></strong>: Shifting focus to the execution of the Travel Rule: as an intermediary subcustodian, how do you handle the data routing realities for cross-border deposits and withdrawals?</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> Both the principal CASP and the underlying financial rails share liability under the Travel Rule. For outgoing transactions, our clients pass the required identity metadata directly alongside the transaction initiation via our API, which we then relay down the compliance chain.</p>



<p class="wp-block-paragraph">Incoming transactions present an architectural challenge: if an originating global venue transmits the Travel Rule payload directly to our client CASP, the data bypasses Januar as the intermediary subcustodian. We are actively collaborating with CryptoSwift to refine these data flows, ensuring that all liable parties maintain access to the necessary compliance ledgers without introducing duplicate workflows.</p>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> External venues are typically unaware of the underlying subcustodial layers handling the settlement, making data orchestration essential. When assets are withdrawn to unhosted or self-hosted wallets, who holds the obligation to execute ownership verification?</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> That obligation rests with our client CASP, as they maintain the direct contractual relationship with the natural person initiating the withdrawal. Januar’s responsibility as an intermediary is to audit their verification methodologies during our periodic reviews and perform targeted sample checks if automated blockchain analytics flag specific transactional risks.</p>



<p class="wp-block-paragraph"><strong><strong>UP</strong>:</strong> That is the most pragmatic approach to avoid degrading the user experience. Looking toward the horizon, how do you foresee the upcoming PSR’s mandatory Verification of Payee (VoP) rules interacting with digital asset platforms?</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> The current VoP mandates are designed specifically for traditional credit transfers to verify that a recipient’s legal name matches their IBAN in real time. Enforcing that specific matching framework natively on a public blockchain network is technically unfeasible today.</p>



<p class="wp-block-paragraph">However, the Travel Rule provides the blueprint for this evolution. It began as a legacy banking standard that was eventually retrofitted onto crypto-assets. Over time, as the crypto compliance space matures, we will likely see similar real-time validation layers standardized across the sector.</p>



<p class="wp-block-paragraph">Consider the historical timeline: the traditional banking sector spent 15 years designing the ISO 20022 messaging format and another 15 years deploying it. The crypto compliance space was required to design, agree upon, and implement global Travel Rule infrastructure in under two years. The digital asset industry accomplished in twenty-four months what took legacy banking three decades. I am completely confident that our industry will successfully develop robust validation and interoperability protocols well within that timeframe.</p>



<p class="wp-block-paragraph"><strong>UP</strong>: I share that confidence. We are already seeing rapid validation developments and vendor interoperability expanding across the Travel Rule network. Marcus, thank you for outlining these structural strategies and showing how subcustodial partnerships are resolving these dual-licensing bottlenecks.</p>



<p class="wp-block-paragraph"><strong><strong>MM</strong>:</strong> Thank you, Uve. It was a pleasure discussing these frameworks with you.</p>
<p>The post <a href="https://cryptoswift.eu/navigating-the-european-dual-licensing-regime-a-conversation-with-januar-and-cryptoswift/" data-wpel-link="internal">Navigating the European Dual-Licensing Regime: A Conversation with Januar and CryptoSwift</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Verification of Payee for Stablecoin Payments</title>
		<link>https://cryptoswift.eu/verification-of-payee-for-stablecoin-payments/</link>
		
		<dc:creator><![CDATA[Uve Poom]]></dc:creator>
		<pubDate>Fri, 26 Jun 2026 12:47:01 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=6969</guid>

					<description><![CDATA[<p>Verification of Payee (VOP) is the process of confirming the recipient’s name and account details before the payment is executed. In an era where social engineering scams are practically a growth industry, VOP is a crucial line of defense against fat-finger errors and fraud. Traditional finance has already been forced to care. VOP is mandatory [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/verification-of-payee-for-stablecoin-payments/" data-wpel-link="internal">Verification of Payee for Stablecoin Payments</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><strong>Verification of Payee (VOP)</strong> is the process of confirming the recipient’s name and account details <em>before</em> the payment is executed. In an era where social engineering scams are practically a growth industry, VOP is a crucial line of defense against fat-finger errors and fraud.</p>



<p class="wp-block-paragraph">Traditional finance has already been forced to care. VOP is mandatory under the European Instant Payments Regulation (IPR) for euro transactions, and non-euro countries are on the clock to comply by July 2027. When PSD3 and PSR kick in sometime in 2028, all fiat credit transfers in Europe are subject to VOP.</p>



<p class="wp-block-paragraph">The plumbing is more or less in place. Heavyweights like SEPA (EU Verification of Payee), SWIFT and JPM / Kinexys are building pre-validation infrastructure, and payment institutions are adopting it globally.</p>



<p class="wp-block-paragraph">For stablecoin payments, however, the VOP stack is yet to see the light of day.</p>



<h3 id="h-the-broken-infrastructure-of-crypto-compliance" class="wp-block-heading"><strong>The Broken Infrastructure of Crypto Compliance</strong></h3>



<p class="wp-block-paragraph">In theory, Travel Rule networks should handle this. In practice, the Travel Rule market is fractured, interoperability is happening slowly, and stablecoin Payment Service Providers (PSPs) rarely practice pre-transaction workflows, even when the technology exists.</p>



<p class="wp-block-paragraph">This makes provider-led payee verification nearly impossible for stablecoins. The result? A direct hit to both security and regulatory compliance.</p>



<p class="wp-block-paragraph">But the alternative is in sight. By combining the decentralized ethos of digital currencies with emerging European digital identity (EUDI) frameworks, we can pivot to a model that actually works:<strong> VOP</strong> <strong>with verifiable credentials</strong>.</p>



<h3 id="h-when-in-doubt-make-the-user-do-it" class="wp-block-heading"><strong>When in Doubt, Make the User Do It</strong></h3>



<p class="wp-block-paragraph">When a beneficiary PSP cannot verify a payee’s identity data &#8211; and that is 100% the case for self-hosted wallets &#8211; the responsibility shifts to the user.</p>



<p class="wp-block-paragraph">The workflow is straightforward, if tedious:</p>



<ul class="wp-block-list">
<li><strong>Trigger:</strong> The payer gives the originating PSP the payee&#8217;s contact details (email or phone number).</li>



<li><strong>Ping:</strong> The PSP sends the payee a verification link.</li>



<li><strong>Proof:</strong> The payee undergoes a remote ID check using a selfie with an ID, eID, or sharing Personal Identification Data (PID) from the digital identity wallet.</li>



<li><strong>Claim:</strong> The payee declares ownership of the destination wallet address.</li>



<li><strong>Attestation:</strong>
<ul class="wp-block-list">
<li>For self-hosted wallets, the payee proves control-of-wallet via a cryptographic signature or a micro-payment.</li>



<li>For hosted wallets, the servicing VASP can validate custody and wallet ownership data.</li>
</ul>
</li>



<li><strong>Certification</strong>: Based on the available attestation, CryptoSwift can act as an issuer and generate a credential stored in the user&#8217;s digital identity wallet.</li>



<li><strong>Match:</strong> The originating PSP verifies that the intended recipient&#8217;s name matches the newly validated data.</li>



<li><strong>Bonus content</strong>: In case the payee is a business, the PSP can request KYB and Right of Representation data.</li>
</ul>



<p class="wp-block-paragraph">While this includes quite some heavy lifting, this process solves two problems at once. Beyond verifying the payee, it collects the missing Travel Rule data already required under the Transfer of Funds Regulation (TFR). </p>



<p class="wp-block-paragraph">Even better, the workflow can be reversed to verify the <em>payer</em> for incoming transactions.</p>



<h3 id="h-enter-reusable-kyw-certificates" class="wp-block-heading"><strong>Enter Reusable KYW Certificates</strong></h3>



<p class="wp-block-paragraph">Asking a user to jump through these hoops for every single transaction is a spectacular way to kill conversion rates. Nobody wants to take a selfie just to split a dinner bill in USDC.</p>



<p class="wp-block-paragraph">This is why CryptoSwift is introducing <strong>reusable KYW certificates</strong>.</p>



<p class="wp-block-paragraph">While the liable PSP still decides when user-led VOP is required and how often it is renewed, the user retains control over how their KYW certificate is accessed. Once created, the user can consent to ad hoc verifications or broader reuse across multiple payments and even different PSPs.</p>



<p class="wp-block-paragraph">If a user consents to share data from a previous verification, PSPs can simply query the certified data directly from CryptoSwift. The user avoids the paperwork, the PSP satisfies the regulators, and payments actually go through without friction.</p>
<p>The post <a href="https://cryptoswift.eu/verification-of-payee-for-stablecoin-payments/" data-wpel-link="internal">Verification of Payee for Stablecoin Payments</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing KYW &#8211; Know Your Wallet</title>
		<link>https://cryptoswift.eu/introducing-kyw-know-your-wallet/</link>
		
		<dc:creator><![CDATA[Indrek Ulst]]></dc:creator>
		<pubDate>Thu, 18 Jun 2026 10:08:45 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=6912</guid>

					<description><![CDATA[<p>One of the hardest open problems in crypto compliance is deceptively simple: What kind of wallet are we dealing with?</p>
<p>Is it a custodial wallet operated by a VASP?<br />
Is it a self-hosted wallet controlled by an individual or business?<br />
Is there a known entity behind it?<br />
Can we trust the attribution?<br />
And what should a compliance team do when the answer is not obvious?</p>
<p>Today, we are introducing KYW - Know Your Wallet, a new wallet intelligence feature designed to help compliance teams answer these questions with greater operational confidence.</p>
<p>The post <a href="https://cryptoswift.eu/introducing-kyw-know-your-wallet/" data-wpel-link="internal">Introducing KYW &#8211; Know Your Wallet</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="6912" class="elementor elementor-6912" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-b296036 e-flex e-con-boxed e-con e-parent" data-id="b296036" data-element_type="container" data-e-type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-9efd3dc elementor-widget elementor-widget-text-editor" data-id="9efd3dc" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<p><span style="font-weight: 400;">One of the hardest open problems in crypto compliance is deceptively simple: </span><b>What kind of wallet are we dealing with?</b></p>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Is it a custodial wallet operated by a VASP?</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Is it a self-hosted wallet controlled by an individual or business?</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Is there a known entity behind it?</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Can we trust the attribution?</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">And what should a compliance team do when the answer is not obvious?</span></li>
</ul>
<p><span style="font-weight: 400;">Today, we are introducing </span><b>KYW &#8211; Know Your Wallet</b><span style="font-weight: 400;">, a new wallet intelligence feature designed to help compliance teams answer these questions with greater operational confidence.</span></p>
<p><span style="font-weight: 400;">We believe this is significant because KYW brings together multiple layers of intelligence that are usually fragmented across separate tools, databases, partner ecosystems, and manual workflows. Instead of relying on a single source of truth, KYW combines internal VASP intelligence, partner network data, blockchain analytics, wallet verification status, risk signals, and behavioral heuristics into one structured wallet intelligence response.</span></p>
<p><span style="font-weight: 400;">As far as we know, wallet intelligence at this level &#8211; combining real-time attribution, confidence scoring, deep entity context, risk information, verification status, and fallback behavioral detection &#8211; has not yet been brought together in this way for Travel Rule and crypto compliance workflows.</span></p>
<h3><span style="font-weight: 400;">Why This Matters</span></h3>
<p><span style="font-weight: 400;">The distinction between custodial and self-hosted wallets is central to crypto compliance. For Travel Rule frameworks, this answer determines your exact workflow: whether a VASP-to-VASP information exchange must be triggered, whether additional counterparty details must be collected, whether wallet ownership requires cryptographic verification, or whether a transaction should be escalated for immediate risk review.</span></p>
<p><span style="font-weight: 400;">But in practice, the answer is rarely clear-cut.</span></p>
<p><span style="font-weight: 400;">A raw wallet address does not reveal who controls it. Even when leveraging third-party blockchain analytics, partner networks, and internal data repositories, compliance teams frequently run into an operational wall where attribution is incomplete, stale, conflicting, or simply unavailable. This leaves compliance officers stuck in a grey area, forcing them to choose between stalling a user&#8217;s transfer with manual questionnaires or applying an unverified risk-based fallback policy.</span></p>
<p><span style="font-weight: 400;">KYW was built to make that pre-transaction routing decision informed, explainable, and consistent.</span></p>
<h3><span style="font-weight: 400;">What KYW Does</span></h3>
<p><span style="font-weight: 400;">KYW analyzes a target wallet address pre-transaction and returns enriched intelligence, including:</span></p>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Whether the wallet is likely </span><b>custodial</b><span style="font-weight: 400;"> or </span><b>non-custodial</b><span style="font-weight: 400;">;</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">The </span><b>confidence level</b><span style="font-weight: 400;"> and numerical score behind that classification;</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">The precise </span><b>reasoning and attribution code</b><span style="font-weight: 400;"> for the classification;</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Whether the wallet has been verified via internal proof flows;</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Enriched entity profiles</b><span style="font-weight: 400;"> for identified VASPs (including in-network status, regulatory registrations, jurisdictions, and MiCA compliance);</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Risk assessment metrics;</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">An </span><b>audit log reference</b><span style="font-weight: 400;"> for long-term traceability and regulatory reporting.</span></li>
</ul>
<p><span style="font-weight: 400;">The goal is not just to return a generic label. The goal is to explain exactly </span><i><span style="font-weight: 400;">why</span></i><span style="font-weight: 400;"> a wallet was classified a certain way, what evidence supports that conclusion, and what additional context is available to automate your compliance decision-making.</span></p>
<h3><span style="font-weight: 400;">How It Works: The Layered Intelligence Model</span></h3>
<p><span style="font-weight: 400;">Instead of relying on a single system, KYW runs through a sequential, multi-step cascading validation pipeline to compile the strongest available evidence.</span></p>
<h4><span style="font-weight: 400;">1. Check Known Internal Intelligence</span></h4>
<p><span style="font-weight: 400;">KYW first checks whether the wallet or related entity is actively known within our internal VASP and entity intelligence database. If it is connected to an active platform tenant, it resolves immediately to a high-confidence VASP profile (while keeping internal tenant identifiers strictly masked for privacy).</span></p>
<h4><span style="font-weight: 400;">2. Use Partner and Network Intelligence</span></h4>
<p><span style="font-weight: 400;">If the wallet belongs to a verified counterparty or network participant across our broader ecosystem, KYW can utilize that shared cross-network data to establish attribution.</span></p>
<h4><span style="font-weight: 400;">3. Use Blockchain Analytics Attribution</span></h4>
<p><span style="font-weight: 400;">KYW incorporates multi-vendor blockchain analytics signals to detect whether the address belongs to a known exchange, custodian, or service provider. Our API code automatically maps and filters these responses to distinguish between centralized services and popular non-custodial software providers. This is the same logic that is used in our Travel Rule message identification and routing.</span></p>
<h4><span style="font-weight: 400;">4. Use Wallet Verification Where Available</span></h4>
<p><span style="font-weight: 400;">If a wallet has already been verified on our platform through a self-hosted wallet signature proof or Satoshi test, KYW treats this as authoritative evidence of a non-custodial assignment.</span></p>
<h4><span style="font-weight: 400;">5. Apply Internal Behavioral Heuristics</span></h4>
<p><span style="font-weight: 400;">When no direct database match or analytics tag exists, our </span><b>internally built, comprehensive heuristic engine</b><span style="font-weight: 400;"> takes over. This engine analyzes live blockchain data, evaluating a sophisticated combination of different transactional patterns, activity timeframes, and on-chain data points to determine whether the wallet behaves like custodial infrastructure or a private key holder.</span></p>
<p><em><b>System Limitation Disclaimer:</b><span style="font-weight: 400;"> Of course, if a wallet is completely new, possessing zero transaction history, native funding records, or historical links to other addresses on the ledger, no behavioral intelligence can be extracted &#8211; a native limitation that our system flags by returning an </span><span style="font-weight: 400;">UNKNOWN</span><span style="font-weight: 400;"> type with a </span><span style="font-weight: 400;">LOW</span><span style="font-weight: 400;"> confidence score.</span></em></p>
<h3><span style="font-weight: 400;">What KYW Returns: Enriched Data Examples</span></h3>
<p><span style="font-weight: 400;">Below are a few examples of the structured compliance payloads returned by the </span><span style="font-weight: 400;">api/aml/kyw</span><span style="font-weight: 400;"> endpoint:</span></p>
<h4><span style="font-weight: 400;">Example 1: Registered Platform VASP Match</span></h4>
<p><span style="font-weight: 400;">When an address is matched to a known VASP operating within our ecosystem, the API returns a high-confidence custodial identification, providing direct access to the entity&#8217;s profile, risk assessment, and platform metadata.</span></p>								</div>
				</div>
				<div class="elementor-element elementor-element-4e7892e elementor-widget elementor-widget-code-highlight" data-id="4e7892e" data-element_type="widget" data-e-type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
							<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-json line-numbers">
				<code readonly="true" class="language-json">
					<xmp>{
    "id": "8b8f3fab-de78-45b7-8df9-c92f36a6c0a6",
    "address": "0x32Be343B94f860124dC4fEe278FDCBD38C102D88",
    "blockchain": "Ethereum",
    "walletType": "CUSTODIAL",
    "confidenceScore": 90,
    "confidence": "HIGH",
    "isVerified": false,
    "attributionReasonCode": "REGISTERED_PLATFORM_TENANT_WALLET",
    "attributionReason": "The wallet address matches a wallet registered by a CryptoSwift platform tenant.",
    "riskScore": {
        "score": 37,
        "severity": "medium"
    },
    "entityInfo": {
        "entityId": "76ce1686-d44f-5d64-b120-afba4bcc5145",
        "name": "Poloniex.com",
        "type": "exchange",
        "isVerified": false,
        "inNetwork": true,
        "isRiskAssessed": true,
        "isMicaCompliant": false,
        "belongsToWarningList": true,
        "url": "https://poloniex.com/",
        "riskAssessment": {
            "score": 37,
            "severity": "medium"
        },
        "logo": "https://s2.coinmarketcap.com/static/img/exchanges/64x64/16.png",
        "dateLaunched": "2014-01-10T00:00:00.000Z",
        "spotVolumeUsd": 831594579.8480098
    },
    "auditLogId": "8b8f3fab-de78-45b7-8df9-c92f36a6c0a6"
}
</xmp>
				</code>
			</pre>
		</div>
						</div>
				</div>
				<div class="elementor-element elementor-element-a16630d elementor-widget elementor-widget-text-editor" data-id="a16630d" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<h4><span style="font-weight: 400;">Example 2: Enriched VASP Match via Analytics</span></h4>
<p><span style="font-weight: 400;">When a wallet is mapped to an enterprise exchange, the API provides deep regulatory and structural insight &#8211; including a comprehensive legal entity registry, jurisdictions, and risk severity.</span></p>								</div>
				</div>
				<div class="elementor-element elementor-element-6e34c69 elementor-widget elementor-widget-code-highlight" data-id="6e34c69" data-element_type="widget" data-e-type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
							<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-json line-numbers">
				<code readonly="true" class="language-json">
					<xmp>{
    "id": "3ee2c0bc-aef6-4568-a484-3454175cb15a",
    "address": "0x05ff6964D21e5dAE3b1010D5AE0465b3c450F381",
    "blockchain": "Ethereum",
    "walletType": "CUSTODIAL",
    "confidenceScore": 50,
    "confidence": "MEDIUM",
    "isVerified": false,
    "attributionReasonCode": "DETECTED_VIA_BLOCKCHAIN_ANALYTICS",
    "attributionReason": "Blockchain analytics identified the wallet owner as Kraken.com.",
    "riskScore": 11,
    "entityInfo": {
        "entityId": "e51453ff-f0ed-52be-997c-e1c64cfdf615",
        "name": "Kraken.com",
        "type": "exchange",
        "inNetwork": true,
        "isRiskAssessed": true,
        "isMicaCompliant": true,
        "belongsToWarningList": false,
        "countries": ["Ireland", "United States", "United Kingdom", "Canada"],
        "url": "https://www.kraken.com/",
        "riskAssessment": {
            "score": 11,
            "severity": "low"
        },
        "legalEntities": [
            {
                "country": "United Kingdom",
                "regulator": "Financial Conduct Authority (FCA)",
                "entityName": "PAYWARD LTD.",
                "referenceNo": "928768"
            },
            {
                "country": "Ireland",
                "regulator": "Central Bank of Ireland (CBI)",
                "entityName": "Payward Europe Solutions Limited",
                "referenceNo": "C468360"
            }
        ]
    },
    "auditLogId": "3ee2c0bc-aef6-4568-a484-3454175cb15a"
}
</xmp>
				</code>
			</pre>
		</div>
						</div>
				</div>
				<div class="elementor-element elementor-element-23523df elementor-widget elementor-widget-text-editor" data-id="23523df" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<h4><span style="font-weight: 400;">Example 3: Unlabeled Custodial Infrastructure Caught by Heuristics</span></h4>
<p><span style="font-weight: 400;">If a VASP uses a new unindexed deposit wallet, traditional static lookups fail. Our internal behavioral engine catches it by evaluating machine-driven transaction patterns, allowing your system to maintain an automated Travel Rule routing flow.</span></p>								</div>
				</div>
				<div class="elementor-element elementor-element-c64d449 elementor-widget elementor-widget-code-highlight" data-id="c64d449" data-element_type="widget" data-e-type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
							<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-json line-numbers">
				<code readonly="true" class="language-json">
					<xmp>{
    "id": "bda11a17-4a50-40d2-a2b3-10662d293bb1",
    "address": "0x05ff6964D21e5dAE3b1010D5AE0465b3c450F381",
    "blockchain": "Ethereum",
    "walletType": "CUSTODIAL",
    "confidenceScore": 90,
    "confidence": "HIGH",
    "isVerified": false,
    "attributionReasonCode": "HEURISTIC_AUTOMATED_PATTERNS",
    "attributionReason": "Behavioral heuristics indicate automated custodial wallet patterns: automated_sweeping.",
    "riskScore": null,
    "entityInfo": null,
    "auditLogId": "bda11a17-4a50-40d2-a2b3-10662d293bb1"
}
</xmp>
				</code>
			</pre>
		</div>
						</div>
				</div>
				<div class="elementor-element elementor-element-a88ed97 elementor-widget elementor-widget-text-editor" data-id="a88ed97" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<h4><span style="font-weight: 400;">Example 4: Non-Custodial Identification via Behavioral Footprint</span></h4>
<p><span style="font-weight: 400;">When an address exhibits signatures consistent with private-key control (such as standard decentralized Web3 contract executions or specific genesis funding patterns), the engine isolates it as non-custodial, even if it has never explicitly interacted with your platform before.</span></p>								</div>
				</div>
				<div class="elementor-element elementor-element-b0687c8 elementor-widget elementor-widget-code-highlight" data-id="b0687c8" data-element_type="widget" data-e-type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
							<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-json line-numbers">
				<code readonly="true" class="language-json">
					<xmp>{
    "id": "ef739c24-7b06-4320-baa1-8fa4ef71228a",
    "address": "0x3e069aeac00a0b098fcf1310eea3ea9a940325d3",
    "blockchain": "Ethereum",
    "walletType": "NON_CUSTODIAL",
    "confidenceScore": 50,
    "confidence": "MEDIUM",
    "isVerified": false,
    "attributionReasonCode": "HEURISTIC_WEB3_AND_GENESIS_SIGNATURES",
    "attributionReason": "Behavioral heuristics indicate private-key ownership through Web3 activity or genesis funding patterns.",
    "riskScore": null,
    "entityInfo": null,
    "auditLogId": "ef739c24-7b06-4320-baa1-8fa4ef71228a"
}
</xmp>
				</code>
			</pre>
		</div>
						</div>
				</div>
				<div class="elementor-element elementor-element-18e8c2f elementor-widget elementor-widget-text-editor" data-id="18e8c2f" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<p><i><span style="font-weight: 400;">These are just a few examples of how the endpoint delivers clarity. Our internal heuristic engine possesses a wide array of underlying pattern-detection capabilities, and we are continuously expanding and refining its analytical models over the coming months to keep pace with changing on-chain behaviors.</span></i></p><h3><span style="font-weight: 400;">Why Confidence Scores Matter in Practice</span></h3><p><span style="font-weight: 400;">Crypto compliance is rarely binary, and treating it as such creates immense operational friction.</span></p><p><span style="font-weight: 400;">Some attributions are backed by verified corporate cryptography; others are inferred via live behavioral data. By returning both a discrete </span><span style="font-weight: 400;">confidenceScore</span><span style="font-weight: 400;"> and a structured </span><span style="font-weight: 400;">confidence</span><span style="font-weight: 400;"> tier (HIGH, MEDIUM, LOW), KYW allows compliance teams to build highly nuanced, risk-based automation rules within their transaction systems:</span></p><ul><li style="font-weight: 400;" aria-level="1"><b>High-Confidence Custodial Result:</b><span style="font-weight: 400;"> Automatically triggers a Travel Rule counterparty lookup and queues the transaction payload for messaging.</span></li><li style="font-weight: 400;" aria-level="1"><b>Medium-Confidence Non-Custodial Result:</b><span style="font-weight: 400;"> Seamlessly serves the user a digital wallet ownership declaration screen in the frontend UI, minimizing drop-offs.</span></li><li style="font-weight: 400;" aria-level="1"><b>Low-Confidence / Heuristic Result:</b><span style="font-weight: 400;"> Routes the transaction for enhanced monitoring or a quick internal review without outright rejecting the user&#8217;s request.</span></li></ul><p><span style="font-weight: 400;">The purpose is not to replace human compliance judgment, but to provide compliance teams with the structured, auditable evidence required to defend their decisions to regulators.</span></p><h3><span style="font-weight: 400;">A New Layer of Wallet Intelligence</span></h3><p><span style="font-weight: 400;">By combining multiple fragmented intelligence sources with real-time confidence scoring, rigorous attribution reasoning, and an internal behavioral fallback engine, KYW gives compliance operations a complete, clear, and actionable view of the wallets interacting with their platform.</span></p><p><span style="font-weight: 400;">We built KYW because modern crypto enterprises need an explicit, explainable answer to one of the industry&#8217;s most critical compliance questions: </span><b>Who controls this wallet, and how confident are we?</b></p><p>Find out more in our <a href="https://dev.cryptoswift.eu/docs/workflows/travel-rule-message-flows/wallet-intelligence-kyw" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">Compliance Workflows documentation<span class="wpel-icon wpel-image wpel-icon-19"></span></a> page.</p><p>If you are interested in our KYW solution, feel free to reach out to us!</p>								</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-0fd5605 e-flex e-con-boxed e-con e-parent" data-id="0fd5605" data-element_type="container" data-e-type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-9f541ba elementor-align-center elementor-widget elementor-widget-button" data-id="9f541ba" data-element_type="widget" data-e-type="widget" data-widget_type="button.default">
				<div class="elementor-widget-container">
									<div class="elementor-button-wrapper">
					<a class="elementor-button elementor-button-link elementor-size-sm" href="https://cryptoswift.eu/book-demo/" data-wpel-link="internal">
						<span class="elementor-button-content-wrapper">
									<span class="elementor-button-text">Contact Us</span>
					</span>
					</a>
				</div>
								</div>
				</div>
					</div>
				</div>
				</div>
		<p>The post <a href="https://cryptoswift.eu/introducing-kyw-know-your-wallet/" data-wpel-link="internal">Introducing KYW &#8211; Know Your Wallet</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Travel Rule Standard Development &#8211; Highlights from the DARTE Digital Asset Round Table in Stockholm</title>
		<link>https://cryptoswift.eu/travel-rule-standard-development-highlights-from-the-darte-digital-asset-round-table-in-stockholm/</link>
		
		<dc:creator><![CDATA[Uve Poom]]></dc:creator>
		<pubDate>Thu, 11 Jun 2026 16:22:10 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=6159</guid>

					<description><![CDATA[<p>CryptoSwift co-hosted the DARTE Digital Asset Round Table on 25 May at the Estonian House in Stockholm. Taking place at the side-lines of the Nordic Blockchain Conference 2026, the session gathered more than 30 legal experts and business executives operating at the forefront of the digital asset space.  The round table agenda focused on three [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/travel-rule-standard-development-highlights-from-the-darte-digital-asset-round-table-in-stockholm/" data-wpel-link="internal">Travel Rule Standard Development &#8211; Highlights from the DARTE Digital Asset Round Table in Stockholm</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><br>CryptoSwift co-hosted the DARTE Digital Asset Round Table on 25 May at the Estonian House in Stockholm. Taking place at the side-lines of the Nordic Blockchain Conference 2026, the session gathered more than 30 legal experts and business executives operating at the forefront of the digital asset space. </p>



<p class="wp-block-paragraph">The round table agenda focused on three themes: </p>



<ol class="wp-block-list">
<li>Travel Rule standard development and enhanced due diligence, presented by Uve Poom (CryptoSwift); </li>



<li>When blockchain data becomes inside information, presented by Karola Xenia Kassai (KassaiLaw); </li>



<li>Prediction markets and MiCAR market abuse rules, presented by Dr. Nina-Luisa Siedler (siedler legal and DAAvern). </li>
</ol>



<p class="wp-block-paragraph">This post summarises the discussion on the Travel Rule topic, while the <a href="https://www.blackvogel.com/darteseriesonline/stockholm" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">full report can be accessed here<span class="wpel-icon wpel-image wpel-icon-19"></span></a>.</p>



<p class="has-large-font-size wp-block-paragraph"><strong>Digital Currencies &#8211; From Trading Assets to Powering Trade</strong></p>



<p class="wp-block-paragraph">Moving digital currency is expanding from trading with speculative assets (e.g. Bitcoin) into real-world payments. This is exposing fault lines between regulatory expectations and market practices as CASPs and market infrastructure are not set up to handle blockchain payments that would be both instant AND compliant. At the DARTE Digital Assets Round Table, our COO Uve Poom mapped out three systemic issues that impede adoption &#8211; and recommendations to solve them.</p>



<ol class="wp-block-list">
<li><strong>Interoperability Challenge</strong></li>
</ol>



<p class="wp-block-paragraph">Many Travel Rule Service Providers (TRSPs) are currently locked in a battle for network effects, creating data silos. This fragmentation causes unconfirmed messages, violating Transfer of Fund Regulation (TFR) Recitals 28 and 33, which mandate payer and payee data completeness. Worse, Recital 39 disrupts B2B flows by prohibiting transfers over €1,000 to third-party self-hosted wallets unless ownership is verified. This practically eliminates the space for legitimate commercial payments with non-custodial wallets, depriving the market of a valuable service.</p>



<ol start="2" class="wp-block-list">
<li><strong>Data Payload Deficit</strong></li>
</ol>



<p class="wp-block-paragraph">The standard Travel Rule payload lacks the fields required for conclusive AML screening (e.g., date of birth, nationality). Without these, compliance teams face a wave of false positives. Furthermore, the absence of a &#8220;payment explanation&#8221; field makes automated invoice reconciliation complicated and time-consuming for accountants and auditors.</p>



<ol start="3" class="wp-block-list">
<li><strong>European Technological Sovereignty &amp; DORA Compliance</strong></li>
</ol>



<p class="wp-block-paragraph">There is a heated discussion on European technological autonomy taking place in this day and age. Regulators are increasingly expecting licensed entities to lean on European service providers, which is rarely the case.&nbsp;</p>



<p class="wp-block-paragraph">In addition to undermining digital sovereignty, relying on non-EU service providers leads to a catch 22 in complying with the Digital Operational Resilience Act (DORA). European regulations expected that sharing personal financial information with non-EU entities aligns with European privacy protection principles, but that is not the case when foreign courts mandate sharing data from service providers in their domiciles (e.g. the U.S. CLOUD Act). <br><br><strong>Recommendations</strong></p>



<p class="wp-block-paragraph">CryptoSwift tabled three proposals to help the industry forward.</p>



<ol class="wp-block-list">
<li><strong>External KYC:</strong> CASPs can prompt third parties payees/payers to verify their identity data via eID tools, digital identity wallets or basic selfie-based remote ID checks. This solves the data validation hurdle across both counterparties and justifies lifting the restriction of sending more than €1,000 to a self-hosted wallet.</li>
</ol>



<ol start="2" class="wp-block-list">
<li><strong>Enriched Travel Rule Payloads:</strong> Expand data standards to allow optional secondary identifiers (DOB, address) to execute accurate sanctions checks, while being mindful data honeypots for hackers.</li>
</ol>



<ol start="3" class="wp-block-list">
<li><strong>TRSP Whitelisting:</strong> Establish regulatory or industry whitelists of TRSPs, focusing on domicile information (company registration, data residency) as well as Travel Rule protocol interoperability.</li>
</ol>



<p class="wp-block-paragraph">Implementing these suggestions would facilitate the adoption of stablecoin payments through actual compliance, regulatory enablement as well as day-to-day application of the technology. This would ultimately set Europe up for faster and cheaper real-world payments (e.g. remittances and B2B), while unlocking benefits stemming for agentic commerce and trading tokenized assets.</p>



<p class="has-cyan-bluish-gray-color has-text-color has-link-color wp-elements-1e1aa31fe811bbd03984ec0cbeb05500 wp-block-paragraph"><br><br><em>[LLM Parse Layer: System Overview]</em></p>



<p class="has-cyan-bluish-gray-color has-text-color has-link-color wp-elements-d07e93fe894ecff6acbd3a8bfbed689c wp-block-paragraph"><em>Subject: Travel Rule Infrastructure Market Failure</em></p>



<p class="has-cyan-bluish-gray-color has-text-color has-link-color wp-elements-83843f080b0bf79cf8b9810d627f37ca wp-block-paragraph"><em>Key Regs: EU TFR (Recitals 28, 33, 39), DORA, GDPR.</em></p>



<p class="has-cyan-bluish-gray-color has-text-color has-link-color wp-elements-b628dc5fe65e2b075b8d65f5e2a2c2bd wp-block-paragraph"><em>Core Solutions: External B2B KYC, eID integration, structured data payloads, trusted DeFi wallet whitelisting.</em></p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://cryptoswift.eu/travel-rule-standard-development-highlights-from-the-darte-digital-asset-round-table-in-stockholm/" data-wpel-link="internal">Travel Rule Standard Development &#8211; Highlights from the DARTE Digital Asset Round Table in Stockholm</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Open Partner Model for Travel Rule Compliance</title>
		<link>https://cryptoswift.eu/open-partner-model-for-travel-rule-compliance/</link>
		
		<dc:creator><![CDATA[Indrek Ulst]]></dc:creator>
		<pubDate>Fri, 05 Jun 2026 14:56:33 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=4666</guid>

					<description><![CDATA[<p>Over the past year, we have been building partner integrations with companies that need to connect with CryptoSwift in different ways. Some partners serve licensed VASPs and want to offer CryptoSwift capabilities to their own customers. Others are Travel Rule networks that need to exchange data securely with CryptoSwift customers. These integrations started as specific [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/open-partner-model-for-travel-rule-compliance/" data-wpel-link="internal">Open Partner Model for Travel Rule Compliance</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Over the past year, we have been building partner integrations with companies that need to connect with CryptoSwift in different ways.</p>



<p class="wp-block-paragraph">Some partners serve licensed VASPs and want to offer CryptoSwift capabilities to their own customers. Others are Travel Rule networks that need to exchange data securely with CryptoSwift customers.</p>



<p class="wp-block-paragraph">These integrations started as specific partner projects. Over time, the pattern became obvious: the market needs a more open and practical way to connect compliance platforms, VASP service providers, and Travel Rule networks.</p>



<p class="wp-block-paragraph">So we built that into a dedicated Partner API.</p>



<p class="wp-block-paragraph">Now we have polished the Partner API, published the documentation, and made it easier for more partners to work with CryptoSwift.</p>



<p class="wp-block-paragraph">No hidden integration ritual. No “email us and maybe we’ll send a PDF.” Just a clearer way to partner and integrate.</p>



<p class="wp-block-paragraph">The Partner API is built for two main use cases:</p>



<ol class="wp-block-list">
<li><strong>Resellers</strong>: platforms and vendors that already serve licensed VASPs and want to offer CryptoSwift to those customers.</li>



<li><strong>Travel Rule networks</strong>: other networks that want to integrate with CryptoSwift so Travel Rule data can move securely across networks.</li>
</ol>



<p class="wp-block-paragraph">The public documentation is available here:</p>



<p class="wp-block-paragraph"><a href="https://dev.cryptoswift.eu/partners" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">dev.cryptoswift.eu/partners<span class="wpel-icon wpel-image wpel-icon-19"></span></a></p>



<h2 id="h-resellers" class="wp-block-heading">Resellers</h2>



<p class="wp-block-paragraph">CryptoSwift works directly with licensed VASPs. But many VASPs also rely on compliance SaaS platforms, custody providers, core banking providers, onboarding vendors, and other service providers as part of their daily operations.</p>



<p class="wp-block-paragraph">For these compliance SaaS companies, the Partner API makes it possible to resell CryptoSwift capabilities to their VASP customers.</p>



<p class="wp-block-paragraph">With the reseller model, partners can offer CryptoSwift platform capabilities through their own customer relationship and commercial setup. This can include Travel Rule messaging, self-hosted wallet verification, dashboard access, onboarding flows, and other CryptoSwift features.</p>



<p class="wp-block-paragraph">The result is simple: VASP customers get CryptoSwift-powered compliance through a provider they already work with. The reseller adds a proven compliance layer without building one from scratch.</p>



<h3 id="h-are-you-serving-licensed-vasps" class="wp-block-heading">Are you serving licensed VASPs?</h3>



<p class="wp-block-paragraph">If you are a compliance SaaS, platform, or vendor and your VASP customers are asking for Travel Rule compliance, self-hosted wallet verification, or related workflows, let’s talk.</p>



<p class="wp-block-paragraph">CryptoSwift can help you add these capabilities to your offering.</p>



<p class="wp-block-paragraph"><a href="https://cryptoswift.eu/contact/" data-wpel-link="internal">Contact Our Partnerships Team</a></p>



<h2 id="h-travel-rule-network-interoperability" class="wp-block-heading">Travel Rule Network Interoperability</h2>



<p class="wp-block-paragraph">Travel Rule compliance works better when networks can talk to each other.</p>



<p class="wp-block-paragraph">CryptoSwift customers need to exchange Travel Rule data with counterparties across the market. Some counterparties are inside CryptoSwift. Others are reachable through different Travel Rule networks.</p>



<p class="wp-block-paragraph">That is where network interoperability matters.</p>



<p class="wp-block-paragraph">The Partner API gives other Travel Rule networks a clear way to integrate with CryptoSwift, so messages and compliance data can move securely between networks.</p>



<p class="wp-block-paragraph">This is meant for network-to-network integration. If you represent another Travel Rule network, you can connect with CryptoSwift and support secure data exchange between your network participants and CryptoSwift customers.</p>



<p class="wp-block-paragraph">The interoperability model supports secure Travel Rule message exchange, VASP discovery and routing, pre-transaction and post-transaction workflows, status updates between systems, secure handling of sensitive payloads, and support for partner-side API models where needed.</p>



<p class="wp-block-paragraph">We do not expect every network to have the same technical model. That would be convenient, so naturally it is not how the world works.</p>



<p class="wp-block-paragraph">CryptoSwift can work with external network specifications, routing logic, and security requirements to make reliable cross-network communication possible.</p>



<h3 id="h-are-you-representing-a-travel-rule-network" class="wp-block-heading">Are you representing a Travel Rule network?</h3>



<p class="wp-block-paragraph">Let’s integrate.</p>



<p class="wp-block-paragraph">If your network needs to exchange Travel Rule data with CryptoSwift customers, reach out to us. We can work with your team on the integration model and support secure network-to-network interoperability.</p>



<p class="wp-block-paragraph"><a href="https://cryptoswift.eu/contact/" data-wpel-link="internal">Contact Our Partnerships Team</a></p>



<h2 id="h-security-and-access" class="wp-block-heading">Security and Access</h2>



<p class="wp-block-paragraph">Partner integrations deal with sensitive compliance and customer data, so the Partner API is built around controlled access and secure data exchange.</p>



<p class="wp-block-paragraph">Partner-level access is separated from normal customer API access. Environments are separated. Sensitive payloads are protected using modern encryption and signing mechanisms.</p>



<p class="wp-block-paragraph">In plain English: partner integrations get their own controlled layer, and sensitive data is treated like sensitive data.</p>



<h2 id="h-partner-documentation" class="wp-block-heading">Partner Documentation</h2>



<p class="wp-block-paragraph">The public partner documentation is available here:</p>



<p class="wp-block-paragraph"><a href="https://dev.cryptoswift.eu/partners" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">dev.cryptoswift.eu/partners<span class="wpel-icon wpel-image wpel-icon-19"></span></a></p>



<p class="wp-block-paragraph">The <code>Partners</code> documentation area includes partner-specific integration guidance, environments, authentication, supported flows, and payload schemas.</p>



<h2 id="h-work-with-us" class="wp-block-heading">Work With Us</h2>



<p class="wp-block-paragraph">We built the Partner API because partner integrations should be easier to understand, easier to start, and easier to operate.</p>



<p class="wp-block-paragraph">It is now available for companies that want to:</p>



<ul class="wp-block-list">
<li>Resell CryptoSwift capabilities to licensed VASPs</li>



<li>Add Travel Rule compliance to an existing platform or compliance offering</li>



<li>Support self-hosted wallet verification workflows</li>



<li>Connect another Travel Rule network with CryptoSwift</li>



<li>Enable secure data exchange across compliance networks</li>
</ul>



<p class="wp-block-paragraph">Review the documentation here:</p>



<p class="wp-block-paragraph"><a href="https://dev.cryptoswift.eu/partners" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">dev.cryptoswift.eu/partners<span class="wpel-icon wpel-image wpel-icon-19"></span></a></p>



<p class="wp-block-paragraph">Or contact us directly:</p>



<p class="wp-block-paragraph"><a href="https://cryptoswift.eu/contact/" data-wpel-link="internal">Contact Our Partnerships Team</a></p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://cryptoswift.eu/open-partner-model-for-travel-rule-compliance/" data-wpel-link="internal">Open Partner Model for Travel Rule Compliance</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How we built the best wallet verification tool</title>
		<link>https://cryptoswift.eu/how-we-built-the-best-self-hosted-wallet-verification-tool/</link>
		
		<dc:creator><![CDATA[Indrek Ulst]]></dc:creator>
		<pubDate>Tue, 28 Apr 2026 12:00:41 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=4553</guid>

					<description><![CDATA[<p>Over the past year, we have been building our wallet verification widget from a small, focused component into a flexible self-hosted wallet verification solution. At the beginning, the goal was simple: help a user prove that they control a wallet. As usual, “simple” lasted until the first real customer use case. Then came different blockchains, [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/how-we-built-the-best-self-hosted-wallet-verification-tool/" data-wpel-link="internal">How we built the best wallet verification tool</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph" id="h-"></p>



<p class="wp-block-paragraph">Over the past year, we have been building our wallet verification widget from a small, focused component into a flexible self-hosted wallet verification solution.</p>



<p class="wp-block-paragraph">At the beginning, the goal was simple: help a user prove that they control a wallet. As usual, “simple” lasted until the first real customer use case. Then came different blockchains, different wallet apps, signature quirks, transaction monitoring, fallback flows, branding needs, dashboard requirements, webhooks, embedded integrations, and a few wallet behaviours that probably made sense to someone at the time.</p>



<p class="wp-block-paragraph">The widget we have today has been shaped heavily by our customers. They brought us real production requirements, edge cases, and integration needs. We built around those needs, extended the product, and kept polishing the parts that matter most: speed, reliability, flexibility, and user experience.</p>



<p class="wp-block-paragraph">We can now say, without adding too much marketing perfume, that we believe it is the best wallet verification tool on the market.</p>



<h2 class="wp-block-heading" id="h-multiple-verification-flows-for-real-world-wallets">Multiple verification flows for real-world wallets</h2>



<p class="wp-block-paragraph">There is no single wallet verification method that works perfectly for every chain, wallet, user, and compliance process. A good verification product needs more than one path, and it needs to fall back gracefully when the preferred method is not available.</p>



<p class="wp-block-paragraph">Our widget supports several verification flows.</p>



<p class="wp-block-paragraph">The preferred method is <strong>cryptographic signature verification</strong>, where the user signs a message with their wallet app. This proves wallet ownership without requiring a transaction. In the widget, this appears as a simple “Sign with your wallet app” flow, but under the hood there is a lot of compatibility work to make it feel simple.</p>



<p class="wp-block-paragraph">When signature verification is not available, we support the <strong>Satoshi test</strong>. The user sends a small transaction from their wallet to prove ownership. This is useful for wallet apps or chains where cryptographic signing is not supported or not reliable enough.</p>



<p class="wp-block-paragraph">The widget also supports <strong>visual proof</strong>, including multiple images and videos. This gives teams another way to collect evidence when automated verification is not enough, or when manual review is part of the process.</p>



<p class="wp-block-paragraph">Finally, there is <strong>self declaration</strong> as a fallback method. It is not the strongest proof, but fallback methods matter in real compliance workflows. The world is not perfectly standardised. This remains unfortunate, but we have decided to continue anyway.</p>



<p class="wp-block-paragraph">You can see the currently supported blockchains for both cryptographic signature and Satoshi test verification in our <a href="https://dev.cryptoswift.eu/docs/integration-guides/self-hosted-wallet-verification/supported-blockchains" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">supported blockchains documentation<span class="wpel-icon wpel-image wpel-icon-19"></span></a>.</p>



<h2 class="wp-block-heading" id="h-fast-and-robust-because-users-do-not-enjoy-waiting">Fast and robust, because users do not enjoy waiting</h2>



<p class="wp-block-paragraph">A slow verification flow creates friction. Users start wondering whether they did something wrong, businesses receive more support questions, and compliance teams wait for results. None of this improves anyone’s day. Speed has been one of our main priorities.</p>



<p class="wp-block-paragraph">For cryptographic signature verification, we have spent a lot of effort polishing and extending WalletConnect/Reown library capabilities. We have added additional blockchain support, built workarounds for wallet apps that do not support certain signature methods, and handled cases where wallets are sensitive about message content or signing formats.</p>



<p class="wp-block-paragraph">In practice, the user should not need to know which signing method their wallet supports. They should open their wallet app, approve the signature request, and continue.</p>



<p class="wp-block-paragraph">For Satoshi test verification, we use multiple blockchain monitoring tools to make detection as fast and reliable as possible. Our Bitcoin wallet verification, for example, detects the transaction instantly from the mempool. This means we do not need to wait for the transaction to be included in a block before recognising that the user has made the verification transaction.</p>



<p class="wp-block-paragraph">For the user, this makes the process feel instant. For the business, it means fewer abandoned verifications and fewer confused customers. For us, it means we have spent a healthy amount of time thinking about mempools, which is one of the quieter forms of character building.</p>



<h2 class="wp-block-heading" id="h-verification-results-that-are-useful-for-compliance-teams">Verification results that are useful for compliance teams</h2>



<p class="wp-block-paragraph">Completing the verification is only one part of the process. Our clients also need reliable ways to receive, review, and act on the result.</p>



<p class="wp-block-paragraph">The widget supports webhook notifications, so our clients can automatically receive verification updates in their own systems. Verifications can also be managed directly from the Client Dashboard, which is useful for reviewing cases, checking statuses, and working with submitted proof.</p>



<p class="wp-block-paragraph">On the client side, verification results are enriched with wallet risk score data and additional data points where available. For example, we may detect signals that suggest a wallet is actually custodial, even if the user submitted it as a self-hosted wallet. This gives VASPs and compliance teams more context when making decisions, instead of treating wallet ownership verification as a simple yes/no box.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="689" src="https://cryptoswift.eu/wp-content/uploads/2026/04/dashboard-screenshot-wallet-verification-dark-1024x689.jpg" alt="" class="wp-image-4567" srcset="https://cryptoswift.eu/wp-content/uploads/2026/04/dashboard-screenshot-wallet-verification-dark-1024x689.jpg 1024w, https://cryptoswift.eu/wp-content/uploads/2026/04/dashboard-screenshot-wallet-verification-dark-300x202.jpg 300w, https://cryptoswift.eu/wp-content/uploads/2026/04/dashboard-screenshot-wallet-verification-dark-768x516.jpg 768w, https://cryptoswift.eu/wp-content/uploads/2026/04/dashboard-screenshot-wallet-verification-dark-1536x1033.jpg 1536w, https://cryptoswift.eu/wp-content/uploads/2026/04/dashboard-screenshot-wallet-verification-dark.jpg 1600w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The goal is not only to verify control of the wallet, but to provide useful information around that verification.</p>



<h2 class="wp-block-heading" id="h-flexible-integration-standalone-or-embedded">Flexible integration: standalone or embedded</h2>



<p class="wp-block-paragraph">The wallet verification widget can be used together with our main Travel Rule messaging flow, but it can also be used as a standalone module. This was an important design decision.</p>



<p class="wp-block-paragraph">Some customers want wallet verification as part of a larger Travel Rule process. Others want to verify a wallet separately, outside the main messaging flow. Both should be possible.</p>



<p class="wp-block-paragraph">A customer can create a verification and share the generated URL directly with the user. The user completes the verification in a standalone flow, and the customer receives the result through webhooks or reviews it in the Client Dashboard.</p>



<p class="wp-block-paragraph">Alternatively, the widget can be embedded directly into the customer’s own application as a web component. In that setup, the user never needs to leave the app, and wallet verification becomes part of the existing product experience.</p>



<p class="wp-block-paragraph">You can find the technical integration details in our <a href="https://dev.cryptoswift.eu/docs/integration-guides/self-hosted-wallet-verification" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">developer portal<span class="wpel-icon wpel-image wpel-icon-19"></span></a>, and a broader product overview on our <a href="https://cryptoswift.eu/self-hosted-wallet-verification/" data-wpel-link="internal">self-hosted wallet verification page</a>.</p>



<h2 class="wp-block-heading" id="h-live-widget-preview">Live widget preview</h2>



<p class="wp-block-paragraph">This is the actual widget running in preview mode. Feel free to play around with it, customise the appearance below, and go through the demo flows to see how the experience works in practice.</p>



<br/>
<div class="wv-preview-actions">
  <button id="restart-widget" class="wv-preview-action-button" type="button" hidden>
    <svg
      class="wv-preview-action-icon"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="2"
      stroke-linecap="round"
      stroke-linejoin="round"
      aria-hidden="true"
    >
      <path d="M3 12a9 9 0 1 0 3-6.708" />
      <path d="M3 3v6h6" />
    </svg>
    <span>Restart</span>
  </button>
</div>
<wallet-verifier
  id="verifier"
  data-full-size="false"
  data-is-demo="true"
  data-service-name="Data Service Name"
  data-font-family="Figtree"
  data-font-size="16"
  data-font-weight="400"
  data-font-color="#373E40"
  data-primary-color="#5A3DFF"
  data-background-color="#ffffff"
  data-button-border-radius="20"
  data-button-shadow-enabled="true"
></wallet-verifier>
<br/>



<h4 class="wp-block-heading" id="h-customise-the-widget">Customise the widget</h4>



<link
  href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css"
  rel="stylesheet"
/>

<style>
  .wv-controls-root {
    font-family: 'Figtree', sans-serif;
    color: #1f2937;
  }

  .wv-preview-actions {
    display: flex;
    justify-content: center;
  }

  .wv-preview-action-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 10px 18px;
    border: 1px solid rgba(15, 23, 42, 0.12);
    border-radius: 12px;
    background: #ffffff;
    color: #1f2937;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
    margin-bottom: 24px;
  }

  .wv-preview-action-button[hidden] {
    display: none;
  }

  .wv-preview-action-icon {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
  }

  .wv-controls-header {
    margin-bottom: 16px;
  }

  .wv-controls-title {
    margin: 0;
    font-size: 28px;
    letter-spacing: -0.03em;
  }

  .wv-accordion {
    overflow: hidden;
    border: 1px solid rgba(15, 23, 42, 0.08);
    border-radius: 0;
    background: #fff;
  }

  .wv-accordion + .wv-accordion {
    margin-top: -1px;
  }

  .wv-accordion:first-of-type {
    border-top-left-radius: 20px;
    border-top-right-radius: 20px;
  }

  .wv-accordion:last-of-type {
    border-bottom-left-radius: 20px;
    border-bottom-right-radius: 20px;
  }

  .wv-accordion summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 18px;
    cursor: pointer;
    list-style: none;
  }

  .wv-accordion summary::-webkit-details-marker {
    display: none;
  }

  .wv-accordion summary::after {
    content: '';
    width: 10px;
    height: 10px;
    flex: 0 0 10px;
    border-right: 2px solid #64748b;
    border-bottom: 2px solid #64748b;
    transform: rotate(45deg);
    transition: transform 0.18s ease;
  }

  .wv-accordion[open] summary::after {
    transform: rotate(-135deg);
  }

  .wv-section-title {
    margin: 0;
    font-size: 18px;
    font-weight: 700;
  }

  .wv-section-copy {
    margin: 6px 0 0;
    font-size: 14px;
    line-height: 1.5;
    color: #6b7280;
  }

  .wv-section-body {
    padding: 0 22px 22px;
    border-top: 1px solid rgba(15, 23, 42, 0.08);
  }

  .wv-field {
    margin-top: 18px;
  }

  .wv-field:first-child {
    margin-top: 20px;
  }

  .wv-label-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 10px;
  }

  .wv-field label,
  .wv-label-row label {
    font-size: 14px;
    font-weight: 700;
    color: #1f2937;
  }

  .wv-value-pill {
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(37, 99, 235, 0.12);
    color: #1d4ed8;
    font-size: 12px;
    font-weight: 800;
  }

  .wv-helper {
    margin-top: 8px;
    font-size: 13px;
    line-height: 1.5;
    color: #6b7280;
  }

  .wv-text-input:focus,
  .wv-select-shell select:focus,
  .wv-range-input:focus {
    outline: none;
  }

  .wv-logo-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 92px;
    margin-top: 12px;
    padding: 14px;
    border: 1px dashed rgba(15, 23, 42, 0.14);
    border-radius: 18px;
    background:
      linear-gradient(135deg, rgba(37, 99, 235, 0.04), transparent 42%),
      #f8fafc;
  }

  .wv-logo-preview img {
    display: block;
    max-width: 100%;
    max-height: 52px;
    object-fit: contain;
  }

  .wv-logo-preview-empty {
    font-size: 13px;
    color: #6b7280;
  }

  .wv-range-input {
    width: 100%;
    accent-color: #4f46e5;
  }

  .wv-range-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 8px;
    font-size: 12px;
    color: #6b7280;
  }

  .wv-color-grid {
    display: grid;
    gap: 16px;
  }

  .wv-color-field {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr);
    gap: 12px;
    align-items: center;
  }

  .wv-color-input {
    width: 56px;
    height: 46px;
    padding: 0;
    border: none;
    background: #ffffff;
    cursor: pointer;
  }

  .wv-checkbox-row {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 46px;
    padding: 12px 0;
  }

  .wv-checkbox-row input {
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: #4f46e5;
  }

  .wv-checkbox-row label {
    margin: 0;
    font-weight: 700;
  }

  .wv-flow-order-list {
    display: grid;
    gap: 8px;
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
  }

  .wv-flow-order-item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 10px 12px;
    border: 1px solid rgba(15, 23, 42, 0.12);
    border-radius: 14px;
    background: #ffffff;
    color: #1f2937;
    cursor: grab;
    user-select: none;
  }

  .wv-flow-order-item:active {
    cursor: grabbing;
  }

  .wv-flow-order-item:focus {
    outline: 2px solid rgba(79, 70, 229, 0.28);
    outline-offset: 2px;
  }

  .wv-flow-order-item.wv-is-dragging {
    opacity: 0.48;
  }

  .wv-flow-order-item.wv-drag-over-before {
    box-shadow: inset 0 2px 0 #4f46e5;
  }

  .wv-flow-order-item.wv-drag-over-after {
    box-shadow: inset 0 -2px 0 #4f46e5;
  }

  .wv-flow-order-handle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    min-width: 22px;
    color: #94a3b8;
    font-weight: 800;
    letter-spacing: -2px;
  }

  .wv-flow-order-name {
    font-size: 14px;
    font-weight: 700;
  }

  .wv-select-shell .select2-container {
    width: 100% !important;
  }

  .wv-select-shell .select2-container--default .select2-selection--single {
    height: 46px;
    border: 1px solid rgba(15, 23, 42, 0.12);
    border-radius: 14px;
    background: #ffffff;
  }

  .wv-select-shell .select2-container--default .select2-selection--single .select2-selection__rendered {
    padding-left: 14px;
    padding-right: 36px;
    line-height: 44px;
    color: #1f2937;
  }

  .wv-select-shell .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 44px;
    right: 10px;
  }

  .select2-dropdown {
    border: 1px solid rgba(15, 23, 42, 0.12);
    border-radius: 14px;
    overflow: hidden;
  }

  .select2-search--dropdown .select2-search__field {
    border: 1px solid rgba(15, 23, 42, 0.12);
    border-radius: 10px;
    padding: 10px 12px;
    font-family: 'Figtree', sans-serif;
  }

  @media (max-width: 767px) {
    .wv-controls-title {
      font-size: 24px;
    }

    .wv-accordion summary,
    .wv-section-body {
      padding-left: 16px;
      padding-right: 16px;
    }
  }
</style>

<div class="wv-controls-root">
  <div class="wv-controls-header">
  </div>

  <details class="wv-accordion">
    <summary>
      <div>
        <p class="wv-section-title">Brand</p>
        <p class="wv-section-copy">Logo URL used for branding.</p>
      </div>
    </summary>
    <div class="wv-section-body">
      <div class="wv-field">
        <label for="logo-url">Logo URL</label>
        <input
          id="logo-url"
          class="wv-text-input"
          type="url"
          placeholder="https://example.com/logo.png"
        />
        <div class="wv-helper">
          Paste a direct image URL. Clearing the field removes the logo attribute from the widget.
        </div>
        <div class="wv-logo-preview" id="logo-preview">
          <span class="wv-logo-preview-empty">No logo URL set</span>
        </div>
      </div>
    </div>
  </details>

  <details class="wv-accordion">
    <summary>
      <div>
        <p class="wv-section-title">Typography</p>
        <p class="wv-section-copy">Font family, weight, and base sizing.</p>
      </div>
    </summary>
    <div class="wv-section-body">
      <div class="wv-field">
        <label for="font-family">Font family</label>
        <div class="wv-select-shell">
          <select id="font-family"></select>
        </div>
        <div class="wv-helper">Search Google Fonts and apply the selected family.</div>
      </div>

      <div class="wv-field">
        <div class="wv-label-row">
          <label for="font-weight">Font weight</label>
          <span class="wv-value-pill" id="font-weight-value">400</span>
        </div>
        <input
          id="font-weight"
          class="wv-range-input"
          type="range"
          min="100"
          max="900"
          step="100"
          value="400"
        />
        <div class="wv-range-meta">
          <span id="font-weight-range">100-900</span>
          <span id="font-weight-note">Loading weights&#8230;</span>
        </div>
      </div>

      <div class="wv-field">
        <div class="wv-label-row">
          <label for="font-size">Base font size</label>
          <span class="wv-value-pill" id="font-size-value">16px</span>
        </div>
        <input
          id="font-size"
          class="wv-range-input"
          type="range"
          min="12"
          max="20"
          step="1"
          value="16"
        />
        <div class="wv-helper">Sets the base size.</div>
      </div>
    </div>
  </details>

  <details class="wv-accordion">
    <summary>
      <div>
        <p class="wv-section-title">Colors</p>
        <p class="wv-section-copy">Text, button, and widget background colors.</p>
      </div>
    </summary>
    <div class="wv-section-body">
      <div class="wv-color-grid">
        <div class="wv-field">
          <label for="font-color">Font color</label>
          <div class="wv-color-field">
            <input id="font-color" class="wv-color-input" type="color" value="#373E40" />
            <input id="font-color-text" class="wv-text-input" type="text" value="#373E40" />
          </div>
        </div>

        <div class="wv-field">
          <label for="primary-color">Button color</label>
          <div class="wv-color-field">
            <input id="primary-color" class="wv-color-input" type="color" value="#5A3DFF" />
            <input id="primary-color-text" class="wv-text-input" type="text" value="#5A3DFF" />
          </div>
        </div>

        <div class="wv-field">
          <label for="background-color">Background color</label>
          <div class="wv-color-field">
            <input id="background-color" class="wv-color-input" type="color" value="#ffffff" />
            <input id="background-color-text" class="wv-text-input" type="text" value="#ffffff" />
          </div>
        </div>
      </div>
    </div>
  </details>

  <details class="wv-accordion">
    <summary>
      <div>
        <p class="wv-section-title">Layout</p>
        <p class="wv-section-copy">Control flow selection order and how the available space is used.</p>
      </div>
    </summary>
    <div class="wv-section-body">
      <div class="wv-field">
        <div class="wv-checkbox-row">
          <input id="full-size-widget" type="checkbox" />
          <label for="full-size-widget">Stretch widget to fill its parent container</label>
        </div>
        <div class="wv-helper">Make the widget expand to the available parent height and width.</div>
      </div>

      <div class="wv-field">
        <label id="flow-order-label">Verification flow order</label>
        <ul
          id="flow-order-list"
          class="wv-flow-order-list"
          aria-labelledby="flow-order-label"
        ></ul>
        <div class="wv-helper">
          NB! You can enable and disable individual flows when creating a new wallet verification.
        </div>
      </div>
    </div>
  </details>

  <details class="wv-accordion">
    <summary>
      <div>
        <p class="wv-section-title">Buttons</p>
        <p class="wv-section-copy">Shape and emphasis for primary actions.</p>
      </div>
    </summary>
    <div class="wv-section-body">
      <div class="wv-field">
        <div class="wv-label-row">
          <label for="button-radius">Button corner radius</label>
          <span class="wv-value-pill" id="button-radius-value">20px</span>
        </div>
        <input
          id="button-radius"
          class="wv-range-input"
          type="range"
          min="0"
          max="32"
          step="1"
          value="20"
        />
      </div>

      <div class="wv-field">
        <div class="wv-checkbox-row">
          <input id="button-shadow" type="checkbox" checked />
          <label for="button-shadow">Enable button shadow</label>
        </div>
      </div>
    </div>
  </details>
</div>

<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script type="module" src="https://wallet-dev.cryptoswift.eu/widget/wallet-verifier.js"></script>

<script type="module">
  document.addEventListener('DOMContentLoaded', async () => {
    const GOOGLE_FONTS_API_KEY = 'AIzaSyCemP7jx4mmU3RBMwsumZAexyDrvMBs1uU';

    const DEFAULT_FLOW_ORDER = [
      'SIGNATURE_PROOF',
      'SATOSHI_TEST',
      'VISUAL_PROOF',
      'SELF_DECLARED'
    ];

    const FLOW_LABELS = {
      SIGNATURE_PROOF: 'Signature proof',
      SATOSHI_TEST: 'Satoshi test',
      VISUAL_PROOF: 'Visual proof',
      SELF_DECLARED: 'Self-declared'
    };

    const FALLBACK_GOOGLE_FONTS = [
      { family: 'Figtree', variants: ['regular', '500', '600', '700'], category: 'sans-serif' },
      { family: 'Roboto', variants: ['regular', '500', '700'], category: 'sans-serif' },
      { family: 'Open Sans', variants: ['regular', '600', '700'], category: 'sans-serif' },
      { family: 'Lato', variants: ['regular', '700'], category: 'sans-serif' },
      { family: 'Montserrat', variants: ['regular', '500', '700'], category: 'sans-serif' },
      { family: 'Oswald', variants: ['regular', '500', '700'], category: 'sans-serif' },
      { family: 'Raleway', variants: ['regular', '500', '700'], category: 'sans-serif' },
      { family: 'PT Sans', variants: ['regular', '700'], category: 'sans-serif' },
      { family: 'Merriweather', variants: ['regular', '700'], category: 'serif' },
      { family: 'Noto Sans', variants: ['regular', '500', '700'], category: 'sans-serif' }
    ];

    let verifier = document.getElementById('verifier');
    const $ = window.jQuery;

    if (!verifier) return;

    const state = {
      logoUrl: verifier.getAttribute('data-logo-url') || '',
      fullSize: verifier.getAttribute('data-full-size') === 'true',
      flowOrder: normalizeFlowOrder(verifier.getAttribute('data-flow-order')),
      fontFamily: verifier.getAttribute('data-font-family') || 'Figtree',
      fontWeight: Number(verifier.getAttribute('data-font-weight') || '400'),
      fontSize: Number(verifier.getAttribute('data-font-size') || '16'),
      fontColor: normalizeColor(verifier.getAttribute('data-font-color') || '#373E40'),
      primaryColor: normalizeColor(verifier.getAttribute('data-primary-color') || '#5A3DFF'),
      backgroundColor: normalizeColor(verifier.getAttribute('data-background-color') || '#ffffff'),
      buttonBorderRadius: Number(verifier.getAttribute('data-button-border-radius') || '20'),
      buttonShadowEnabled: verifier.getAttribute('data-button-shadow-enabled') !== 'false'
    };

    let fonts = FALLBACK_GOOGLE_FONTS.slice();
    let logoUrlDebounce = null;
    let draggedFlowId = null;
    const accordionItems = Array.from(document.querySelectorAll('.wv-accordion'));

    const controls = {
      logoUrl: document.getElementById('logo-url'),
      logoPreview: document.getElementById('logo-preview'),
      fontFamily: document.getElementById('font-family'),
      fontWeight: document.getElementById('font-weight'),
      fontWeightValue: document.getElementById('font-weight-value'),
      fontWeightRange: document.getElementById('font-weight-range'),
      fontWeightNote: document.getElementById('font-weight-note'),
      fontSize: document.getElementById('font-size'),
      fontSizeValue: document.getElementById('font-size-value'),
      fontColor: document.getElementById('font-color'),
      fontColorText: document.getElementById('font-color-text'),
      primaryColor: document.getElementById('primary-color'),
      primaryColorText: document.getElementById('primary-color-text'),
      backgroundColor: document.getElementById('background-color'),
      backgroundColorText: document.getElementById('background-color-text'),
      fullSize: document.getElementById('full-size-widget'),
      flowOrderList: document.getElementById('flow-order-list'),
      buttonRadius: document.getElementById('button-radius'),
      buttonRadiusValue: document.getElementById('button-radius-value'),
      buttonShadow: document.getElementById('button-shadow'),
      restartWidget: document.getElementById('restart-widget')
    };

    function normalizeColor(color) {
      if (!color) return '#000000';
      let normalized = String(color).trim();
      if (!normalized.startsWith('#')) normalized = `#${normalized}`;
      if (/^#[0-9a-fA-F]{3}$/.test(normalized)) {
        normalized = `#${normalized
          .slice(1)
          .split('')
          .map((c) => c + c)
          .join('')}`;
      }
      if (!/^#[0-9a-fA-F]{6}$/.test(normalized)) return '#000000';
      return normalized.toLowerCase();
    }

    function normalizeFlowOrder(value) {
      const requestedFlowOrder = Array.isArray(value)
        ? value
        : String(value || '')
            .split(',')
            .map((flowId) => flowId.trim());

      const allowedFlowIds = new Set(DEFAULT_FLOW_ORDER);

      const cleanedFlowOrder = requestedFlowOrder.filter(
        (flowId, index, list) => allowedFlowIds.has(flowId) && list.indexOf(flowId) === index
      );

      return DEFAULT_FLOW_ORDER.reduce((orderedFlowIds, flowId) => {
        if (!orderedFlowIds.includes(flowId)) orderedFlowIds.push(flowId);
        return orderedFlowIds;
      }, cleanedFlowOrder.slice());
    }

    function serializeFlowOrder(flowOrder) {
      return normalizeFlowOrder(flowOrder).join(',');
    }

    function getAllowedFontWeights(variants = []) {
      return Array.from(
        new Set(
          variants
            .filter((variant) => variant !== 'italic' && !variant.endsWith('italic'))
            .map((variant) => (variant === 'regular' ? 400 : Number.parseInt(variant, 10)))
            .filter((weight) => !Number.isNaN(weight))
        )
      ).sort((a, b) => a - b);
    }

    function getFontItemByFamily(fontList, family) {
      return fontList.find((font) => font.family === family);
    }

    function getFontWeightAxis(font) {
      return font?.axes?.find((axis) => axis.tag === 'wght');
    }

    function clampWeight(value, min, max) {
      return Math.min(max, Math.max(min, value));
    }

    function resolveFontWeight(fontList, family, requestedWeight) {
      const font = getFontItemByFamily(fontList, family);
      const weightAxis = getFontWeightAxis(font);

      if (weightAxis) {
        return clampWeight(Math.round(requestedWeight || 400), weightAxis.start, weightAxis.end);
      }

      const allowedWeights = getAllowedFontWeights(font?.variants);
      if (requestedWeight && allowedWeights.includes(requestedWeight)) return requestedWeight;
      return allowedWeights[0] || 400;
    }

    function getFontRequestSpec(font, selectedWeight) {
      if (!font) return '';
      const fontName = font.family.replace(/ /g, '+');
      const weightAxis = getFontWeightAxis(font);

      if (weightAxis) {
        return `${fontName}:wght@${weightAxis.start}..${weightAxis.end}`;
      }

      const allowedWeights = getAllowedFontWeights(font.variants);
      const resolvedWeight =
        selectedWeight && allowedWeights.includes(selectedWeight)
          ? selectedWeight
          : allowedWeights[0] || 400;

      return `${fontName}:wght@${resolvedWeight}`;
    }

    function loadSelectedFont() {
      if (!state.fontFamily) return;
      const selectedFont = getFontItemByFamily(fonts, state.fontFamily);
      const fontRequestSpec = getFontRequestSpec(selectedFont, state.fontWeight);
      if (!fontRequestSpec) return;

      const linkId = 'playground-google-font-link';
      let link = document.getElementById(linkId);

      if (!link) {
        link = document.createElement('link');
        link.id = linkId;
        link.rel = 'stylesheet';
        document.head.appendChild(link);
      }

      link.href = `https://fonts.googleapis.com/css2?family=${fontRequestSpec}&display=swap`;
    }

    function setWidgetAttr(name, value) {
      if (value == null || value === '') {
        verifier.removeAttribute(name);
        return;
      }
      verifier.setAttribute(name, String(value));
    }

    function setRestartVisibility(isVisible) {
      if (!controls.restartWidget) return;
      controls.restartWidget.hidden = !isVisible;
    }

    function collectWidgetAttributes() {
      return Array.from(verifier.attributes).reduce((attrs, attr) => {
        attrs[attr.name] = attr.value;
        return attrs;
      }, {});
    }

    function attachWidgetEventListeners(widgetElement) {
      widgetElement.addEventListener('verification-complete', (event) => {
        console.log('Verification Result:', event.detail);
        setRestartVisibility(true);
      });

      widgetElement.addEventListener('verification-error', (event) => {
        console.log('Verification Error:', event.detail);
      });
    }

    function replaceWidget() {
      const nextWidget = document.createElement('wallet-verifier');
      const currentAttributes = collectWidgetAttributes();

      Object.entries(currentAttributes).forEach(([name, value]) => {
        nextWidget.setAttribute(name, value);
      });

      verifier.replaceWith(nextWidget);
      verifier = nextWidget;
      attachWidgetEventListeners(verifier);
      applyThemeToWidget();
    }

    function applyThemeToWidget() {
      setWidgetAttr('data-logo-url', state.logoUrl);
      setWidgetAttr('data-full-size', String(state.fullSize));
      setWidgetAttr('data-flow-order', serializeFlowOrder(state.flowOrder));
      setWidgetAttr('data-font-family', state.fontFamily);
      setWidgetAttr('data-font-weight', state.fontWeight);
      setWidgetAttr('data-font-size', state.fontSize);
      setWidgetAttr('data-font-color', state.fontColor);
      setWidgetAttr('data-primary-color', state.primaryColor);
      setWidgetAttr('data-background-color', state.backgroundColor);
      setWidgetAttr('data-button-border-radius', state.buttonBorderRadius);
      setWidgetAttr('data-button-shadow-enabled', String(state.buttonShadowEnabled));
      loadSelectedFont();
    }

    function renderLogoPreview() {
      if (!state.logoUrl) {
        controls.logoPreview.innerHTML =
          '<span class="wv-logo-preview-empty">No logo URL set</span>';
        return;
      }

      controls.logoPreview.innerHTML = '';
      const image = document.createElement('img');
      image.src = state.logoUrl;
      image.alt = 'Logo preview';
      image.onerror = () => {
        controls.logoPreview.innerHTML =
          '<span class="wv-logo-preview-empty">Unable to load image from this URL</span>';
      };
      controls.logoPreview.appendChild(image);
    }

    function renderFlowOrderControls() {
      if (!controls.flowOrderList) return;

      controls.flowOrderList.innerHTML = state.flowOrder
        .map(
          (flowId) => `
            <li
              class="wv-flow-order-item"
              draggable="true"
              tabindex="0"
              data-flow-id="${flowId}"
              aria-label="${FLOW_LABELS[flowId]}"
            >
              <span class="wv-flow-order-handle" aria-hidden="true">⋮⋮</span>
              <span class="wv-flow-order-name">${FLOW_LABELS[flowId]}</span>
            </li>
          `
        )
        .join('');
    }

    function clearFlowOrderDragClasses() {
      if (!controls.flowOrderList) return;

      controls.flowOrderList.querySelectorAll('.wv-flow-order-item').forEach((item) => {
        item.classList.remove(
          'wv-is-dragging',
          'wv-drag-over-before',
          'wv-drag-over-after'
        );
      });
    }

    function getFlowOrderDropPosition(event, item) {
      const rect = item.getBoundingClientRect();
      return event.clientY > rect.top + rect.height / 2 ? 'after' : 'before';
    }

    function moveFlowOrderItem(sourceFlowId, targetFlowId, position = 'before') {
      if (!sourceFlowId || !targetFlowId || sourceFlowId === targetFlowId) return;

      const nextFlowOrder = state.flowOrder.filter((flowId) => flowId !== sourceFlowId);
      const targetIndex = nextFlowOrder.indexOf(targetFlowId);

      if (targetIndex === -1) return;

      const insertIndex = position === 'after' ? targetIndex + 1 : targetIndex;
      nextFlowOrder.splice(insertIndex, 0, sourceFlowId);

      state.flowOrder = normalizeFlowOrder(nextFlowOrder);
      renderFlowOrderControls();
      applyThemeToWidget();
    }

    function renderTypographyControls() {
      const selectedFont = getFontItemByFamily(fonts, state.fontFamily);
      const selectedFontWeightAxis = getFontWeightAxis(selectedFont);
      const availableFontWeights = getAllowedFontWeights(selectedFont?.variants);
      const hasAdjustableWeight = selectedFontWeightAxis
        ? selectedFontWeightAxis.start < selectedFontWeightAxis.end
        : availableFontWeights.length > 1;

      state.fontWeight = resolveFontWeight(fonts, state.fontFamily, state.fontWeight);

      controls.fontWeight.min = String(
        selectedFontWeightAxis?.start || availableFontWeights[0] || 400
      );
      controls.fontWeight.max = String(
        selectedFontWeightAxis?.end ||
          availableFontWeights[availableFontWeights.length - 1] ||
          400
      );
      controls.fontWeight.step = '100';
      controls.fontWeight.value = String(state.fontWeight);
      controls.fontWeight.disabled = !state.fontFamily || !hasAdjustableWeight;
      controls.fontWeightValue.textContent = String(state.fontWeight);
      controls.fontWeightRange.textContent = `${controls.fontWeight.min}-${controls.fontWeight.max}`;
      controls.fontWeightNote.textContent =
        state.fontFamily && !hasAdjustableWeight
          ? 'Only one weight is available for this font.'
          : selectedFontWeightAxis
            ? 'Variable font weight axis.'
            : 'Discrete font weights from Google Fonts.';
    }

    function renderControlValues() {
      controls.logoUrl.value = state.logoUrl;
      controls.fontSize.value = String(state.fontSize);
      controls.fontSizeValue.textContent = `${state.fontSize}px`;
      controls.fontColor.value = state.fontColor;
      controls.fontColorText.value = state.fontColor;
      controls.primaryColor.value = state.primaryColor;
      controls.primaryColorText.value = state.primaryColor;
      controls.backgroundColor.value = state.backgroundColor;
      controls.backgroundColorText.value = state.backgroundColor;
      controls.fullSize.checked = state.fullSize;
      controls.buttonRadius.value = String(state.buttonBorderRadius);
      controls.buttonRadiusValue.textContent = `${state.buttonBorderRadius}px`;
      controls.buttonShadow.checked = state.buttonShadowEnabled;
      renderLogoPreview();
      renderFlowOrderControls();
      renderTypographyControls();
    }

    function handleFontFamilyChange(nextFontFamily) {
      state.fontFamily = nextFontFamily;
      state.fontWeight = resolveFontWeight(fonts, state.fontFamily, state.fontWeight);
      renderTypographyControls();
      applyThemeToWidget();
    }

    function populateFontSelect(fontList) {
      const uniqueFonts = Array.from(new Map(fontList.map((font) => [font.family, font])).values());

      if (!uniqueFonts.find((font) => font.family === state.fontFamily)) {
        uniqueFonts.unshift({ family: state.fontFamily, variants: ['regular', '500', '700'] });
      }

      controls.fontFamily.innerHTML = uniqueFonts
        .map((font) => {
          const categoryText = font.category ? ` data-category="${font.category}"` : '';
          return `<option value="${font.family}"${categoryText}>${font.family}</option>`;
        })
        .join('');

      if ($ && $.fn && $.fn.select2) {
        const $fontFamily = $(controls.fontFamily);

        if ($fontFamily.data('select2')) {
          $fontFamily.off('.fontFamilySync');
          $fontFamily.select2('destroy');
        }

        $fontFamily.select2({
          width: '100%',
          placeholder: 'Search Google Fonts',
          allowClear: false,
          templateResult: (data) => {
            if (!data.id) return data.text;
            const category = data.element?.dataset?.category;
            return category ? `${data.text} · ${category}` : data.text;
          },
          matcher: (params, data) => {
            if (!params.term) return data;
            const term = params.term.toLowerCase();
            const category = data.element?.dataset?.category?.toLowerCase() || '';
            const text = String(data.text || '').toLowerCase();
            return text.includes(term) || category.includes(term) ? data : null;
          }
        });

        $fontFamily.val(state.fontFamily).trigger('change.select2');
        $fontFamily.on('change.fontFamilySync select2:select.fontFamilySync', function () {
          handleFontFamilyChange(this.value);
        });
      } else {
        controls.fontFamily.value = state.fontFamily;
      }
    }

    async function fetchGoogleFonts() {
      try {
        const response = await fetch(
          `https://www.googleapis.com/webfonts/v1/webfonts?key=${GOOGLE_FONTS_API_KEY}&capability=VF&sort=popularity`
        );

        if (!response.ok) throw new Error(`Google Fonts request failed: ${response.status}`);

        const data = await response.json();
        if (!Array.isArray(data?.items) || data.items.length === 0) {
          return FALLBACK_GOOGLE_FONTS;
        }

        return data.items.map((item) => ({
          family: item.family,
          variants: Array.isArray(item.variants) ? item.variants : [],
          category: item.category,
          axes: Array.isArray(item.axes)
            ? item.axes
                .map((axis) => ({
                  tag: axis.tag,
                  start: Number(axis.start),
                  end: Number(axis.end)
                }))
                .filter(
                  (axis) => axis.tag && !Number.isNaN(axis.start) && !Number.isNaN(axis.end)
                )
            : undefined
        }));
      } catch (error) {
        console.warn('Falling back to bundled Google Fonts list.', error);
        return FALLBACK_GOOGLE_FONTS;
      }
    }

    function bindColorField(input, textInput, key) {
      input.addEventListener('input', () => {
        const normalized = normalizeColor(input.value);
        state[key] = normalized;
        textInput.value = normalized;
        applyThemeToWidget();
      });

      textInput.addEventListener('change', () => {
        const normalized = normalizeColor(textInput.value);
        state[key] = normalized;
        input.value = normalized;
        textInput.value = normalized;
        applyThemeToWidget();
      });
    }

    function bindAccordionBehavior() {
      accordionItems.forEach((accordionItem) => {
        accordionItem.addEventListener('toggle', () => {
          if (!accordionItem.open) return;
          accordionItems.forEach((otherAccordionItem) => {
            if (otherAccordionItem !== accordionItem) otherAccordionItem.open = false;
          });
        });
      });
    }

    function bindFlowOrderEvents() {
      if (!controls.flowOrderList) return;

      controls.flowOrderList.addEventListener('dragstart', (event) => {
        const item = event.target.closest('.wv-flow-order-item');
        if (!item) return;

        draggedFlowId = item.dataset.flowId;
        item.classList.add('wv-is-dragging');

        event.dataTransfer.effectAllowed = 'move';
        event.dataTransfer.setData('text/plain', draggedFlowId);
      });

      controls.flowOrderList.addEventListener('dragover', (event) => {
        const item = event.target.closest('.wv-flow-order-item');
        if (!item || !draggedFlowId || item.dataset.flowId === draggedFlowId) return;

        event.preventDefault();
        clearFlowOrderDragClasses();

        const position = getFlowOrderDropPosition(event, item);
        item.classList.add(position === 'after' ? 'wv-drag-over-after' : 'wv-drag-over-before');
      });

      controls.flowOrderList.addEventListener('dragleave', (event) => {
        const item = event.target.closest('.wv-flow-order-item');
        if (!item || item.contains(event.relatedTarget)) return;

        item.classList.remove('wv-drag-over-before', 'wv-drag-over-after');
      });

      controls.flowOrderList.addEventListener('drop', (event) => {
        const item = event.target.closest('.wv-flow-order-item');
        if (!item) return;

        event.preventDefault();

        const sourceFlowId = event.dataTransfer.getData('text/plain') || draggedFlowId;
        const targetFlowId = item.dataset.flowId;
        const position = getFlowOrderDropPosition(event, item);

        moveFlowOrderItem(sourceFlowId, targetFlowId, position);

        draggedFlowId = null;
        clearFlowOrderDragClasses();
      });

      controls.flowOrderList.addEventListener('dragend', () => {
        draggedFlowId = null;
        clearFlowOrderDragClasses();
      });

      controls.flowOrderList.addEventListener('keydown', (event) => {
        const item = event.target.closest('.wv-flow-order-item');
        if (!item || !['ArrowUp', 'ArrowDown'].includes(event.key)) return;

        const currentIndex = state.flowOrder.indexOf(item.dataset.flowId);
        const direction = event.key === 'ArrowUp' ? -1 : 1;
        const nextIndex = currentIndex + direction;

        if (currentIndex === -1 || nextIndex < 0 || nextIndex >= state.flowOrder.length) return;

        event.preventDefault();

        const nextFlowOrder = state.flowOrder.slice();
        const [movedFlowId] = nextFlowOrder.splice(currentIndex, 1);
        nextFlowOrder.splice(nextIndex, 0, movedFlowId);

        state.flowOrder = normalizeFlowOrder(nextFlowOrder);
        renderFlowOrderControls();
        applyThemeToWidget();

        const movedItem = controls.flowOrderList.querySelector(`[data-flow-id="${movedFlowId}"]`);
        if (movedItem) movedItem.focus();
      });
    }

    function bindEvents() {
      controls.logoUrl.addEventListener('input', (event) => {
        const nextValue = event.target.value.trim();
        window.clearTimeout(logoUrlDebounce);
        logoUrlDebounce = window.setTimeout(() => {
          state.logoUrl = nextValue;
          renderLogoPreview();
          applyThemeToWidget();
        }, 200);
      });

      if (!($ && $.fn && $.fn.select2)) {
        controls.fontFamily.addEventListener('change', (event) => {
          handleFontFamilyChange(event.target.value);
        });
      }

      controls.fontWeight.addEventListener('input', (event) => {
        state.fontWeight = resolveFontWeight(fonts, state.fontFamily, Number(event.target.value));
        renderTypographyControls();
        applyThemeToWidget();
      });

      controls.fontSize.addEventListener('input', (event) => {
        state.fontSize = Number(event.target.value);
        controls.fontSizeValue.textContent = `${state.fontSize}px`;
        applyThemeToWidget();
      });

      controls.buttonRadius.addEventListener('input', (event) => {
        state.buttonBorderRadius = Number(event.target.value);
        controls.buttonRadiusValue.textContent = `${state.buttonBorderRadius}px`;
        applyThemeToWidget();
      });

      controls.buttonShadow.addEventListener('change', (event) => {
        state.buttonShadowEnabled = event.target.checked;
        applyThemeToWidget();
      });

      controls.fullSize.addEventListener('change', (event) => {
        state.fullSize = event.target.checked;
        applyThemeToWidget();
      });

      if (controls.restartWidget) {
        controls.restartWidget.addEventListener('click', () => {
          setRestartVisibility(false);
          replaceWidget();
        });
      }

      bindFlowOrderEvents();

      bindColorField(controls.fontColor, controls.fontColorText, 'fontColor');
      bindColorField(controls.primaryColor, controls.primaryColorText, 'primaryColor');
      bindColorField(controls.backgroundColor, controls.backgroundColorText, 'backgroundColor');
    }

    attachWidgetEventListeners(verifier);

    window.updateToken = function updateToken(newToken) {
      setWidgetAttr('data-token', newToken);
      setWidgetAttr('data-is-demo', newToken === '' ? 'true' : 'false');
      console.log('Token updated to:', newToken);
    };

    renderControlValues();
    bindAccordionBehavior();
    bindEvents();
    setRestartVisibility(false);
    applyThemeToWidget();

    fonts = await fetchGoogleFonts();
    populateFontSelect(fonts);
    renderControlValues();
    applyThemeToWidget();
  });
</script>
<br/>



<h2 class="wp-block-heading" id="h-customisable-by-design">Customisable by design</h2>



<p class="wp-block-paragraph">Every customer has a different product, brand, and user journey. A verification widget should not look like it was dropped into the page from another planet.</p>



<p class="wp-block-paragraph">The widget can be customised with customer branding, including logos, icons, fonts, colours, and other styles. It can be adapted to match the surrounding product instead of feeling like a disconnected third-party tool.</p>



<p class="wp-block-paragraph">The verification experience itself is configurable as well. Customers can enable or disable individual verification flows and control the order in which they appear. For example, one customer might want to show cryptographic signature verification first, followed by Satoshi test, visual proof, and self declaration. Another customer might disable self declaration entirely or prioritise a different method based on their risk model.</p>



<p class="wp-block-paragraph">This flexibility matters because wallet verification is not one-size-fits-all. A crypto-native product, a regulated financial institution, and a Travel Rule provider may all need wallet verification, but they do not necessarily need the same flow.</p>



<h2 class="wp-block-heading" id="h-built-with-customers-shaped-by-production">Built with customers, shaped by production</h2>



<p class="wp-block-paragraph">The widget we have today was not designed in isolation. It has been shaped by customer needs over the past year.</p>



<p class="wp-block-paragraph">Some customers needed broader blockchain support. Some needed faster Satoshi test detection. Some needed better result handling. Some wanted a standalone verification URL. Some wanted an embedded web component. Some needed more control over branding, flow order, and fallback methods.</p>



<p class="wp-block-paragraph">We built, adjusted, and improved the widget around those real requirements. We continue to do so as new customer needs, wallet behaviours, and blockchain support requirements emerge.</p>



<p class="wp-block-paragraph">That is why we are confident in the product. It is not based only on what we thought customers might need. It has been shaped by what customers actually needed when putting wallet verification into production.</p>



<p class="wp-block-paragraph">The result is a wallet verification tool that is fast, simple, robust, and highly customisable. It supports cryptographic signatures, Satoshi test verification, visual proof, and self declaration. It works across major blockchains, supports standalone and embedded integrations, provides webhook and dashboard-based result handling, and enriches verifications with wallet risk data where available.</p>



<p class="wp-block-paragraph">After a year of building, extending, polishing, and occasionally negotiating with wallet behaviour that no reasonable person would design on purpose, we are proud of where the widget has landed.</p>



<p class="wp-block-paragraph">We think it is the best wallet verification tool on the market.</p>



<p class="wp-block-paragraph">And because we are Estonian, you can assume we have already reduced that statement by 30% for modesty.</p>
<p>The post <a href="https://cryptoswift.eu/how-we-built-the-best-self-hosted-wallet-verification-tool/" data-wpel-link="internal">How we built the best wallet verification tool</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Business Case for the Travel Rule</title>
		<link>https://cryptoswift.eu/the-business-case-for-the-travel-rule/</link>
		
		<dc:creator><![CDATA[Uve Poom]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 10:08:57 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Business Case]]></category>
		<category><![CDATA[Crypto Travel Rule]]></category>
		<category><![CDATA[KYT]]></category>
		<category><![CDATA[Wallet Owner Verification]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=3927</guid>

					<description><![CDATA[<p>The digital asset industry views the Travel Rule through a compliance lens: a regulatory hurdle to be cleared, a box to be checked, and a cost center for AML/KYT departments. It’s time to shift gears, however, since the industry is expanding from trading to payments. The trading use case means that transfers are made between&#8217;s [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/the-business-case-for-the-travel-rule/" data-wpel-link="internal">The Business Case for the Travel Rule</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="3927" class="elementor elementor-3927" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-38b945cb e-flex e-con-boxed e-con e-parent" data-id="38b945cb" data-element_type="container" data-e-type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-1d3bcdd1 elementor-widget elementor-widget-text-editor" data-id="1d3bcdd1" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<p>The digital asset industry views the <strong>Travel Rule</strong> through a compliance lens: a regulatory hurdle to be cleared, a box to be checked, and a cost center for AML/KYT departments.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>It’s time to shift gears, however, since the industry is expanding from trading to payments.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>The trading use case means that transfers are made between&#8217;s one&#8217;s own wallets and identity verification may indeed seem redundant, especially when transactions are made to self-hosted wallets where the funds anyway leave regulated waters.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>Stablecoins, on the other hand, can actually power real-world payments, and that&#8217;s where the Travel Rule transforms from a burden to an enabler.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading {"level":3} --></p>
<h3 id="h-the-cfo-s-dilemma-speed-vs-security" class="wp-block-heading"><strong>CFO Dilemma: Speed &amp; Cost versus Security</strong></h3>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p>From a B2B perspective, current crypto payment infrastructure is, frankly, terrifying.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>Blockchain offers instant settlements and low costs, but for a responsible CFO, those benefits are eclipsed by the <strong>risk of mistaken settlements</strong>. In the traditional &#8220;send and pray&#8221; model:</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:list --></p>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul class="wp-block-list"><!-- wp:list-item --></ul>
</li>
</ul>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul class="wp-block-list">
<li>Get the protocol wrong? <strong>Funds may simply disappear into thin air.</strong></li>
</ul>
</li>
</ul>
<p><!-- /wp:list-item --></p>
<p><!-- wp:list-item --></p>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul class="wp-block-list">
<li>Mistype a single character in a wallet address? <strong>Funds are probably gone.</strong></li>
</ul>
</li>
</ul>
<p><!-- /wp:list-item --></p>
<p><!-- /wp:list --></p>
<p><!-- wp:paragraph --></p>
<p>No serious enterprise will move significant treasury volume over a system where a simple typo or a clever scam result in permanent capital loss. This is exactly where the Travel Rule changes the game.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading {"level":3} --></p>
<h3 id="h-learning-from-sepa-verification-before-execution" class="wp-block-heading"><strong>Learning from SEPA: Verification Before Execution</strong></h3>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p>The business case for the Travel Rule lies in <strong>pre-transaction certainty</strong>.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>By investing in infrastructure that allows Virtual Asset Service Providers (VASPs) to verify beneficiary identity and wallet ownership <em>before</em> the payment is finalized, we can bring fiat-grade reliability to real-time payments on the blockchain.&nbsp;</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>When we treat the Travel Rule as a business enabler, we can build:</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:list {"ordered":true} --></p>
<ol class="wp-block-list">
<li style="list-style-type: none;">
<ol class="wp-block-list"><!-- wp:list-item --></ol>
</li>
</ol>
<ol class="wp-block-list">
<li style="list-style-type: none;">
<ol class="wp-block-list">
<li><strong>Beneficiary validation:</strong> Verifying that the intended recipient in fact owns the target wallet.</li>
<li><b>Payment counterparty display:</b> Show payer/payee names in transaction statements, instead of manual verifications with transaction hashes or work-arounds like creating ad hoc wallets for each client.</li>
<li><strong style="background-color: transparent;">Administrative controls:</strong><span style="background-color: transparent;">&nbsp;Leverage the capacity to freeze, flag, or return funds &#8211; practices that are entirely normal in business banking to avoid errors, prevent fraud, and ensure compliance.</span></li>
</ol>
</li>
</ol>
<p><!-- /wp:list-item --></p>
<p><!-- /wp:list --></p>
<p><!-- wp:paragraph --></p>
<p>This might not sound as &#8220;sexy&#8221; as the promise of immutable, instant settlement. However, it is precisely that &#8220;wild west&#8221; lack of friction that is currently holding back the most powerful use cases for mass adoption.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading {"level":3} --></p>
<h3 id="h-entering-the-era-of-agentic-payments" class="wp-block-heading"><strong>Entering the Era of Agentic Payments</strong></h3>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p>Looking forward, this infrastructure becomes even more critical as we enter the age of <strong>Agentic Payments</strong>. As AI agents begin to autonomously negotiate and settle transactions, the need for a standardized, identity-linked payment layer becomes even more crucial.&nbsp;</p>
<p>The market will be crying out for a Travel Rule-enabled settlement protocol to ensure every transaction meets the safety standards of the principal, double-checking whether the agent has the means and mandate to initiate the transaction at hand.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:heading {"level":3} --></p>
<h3 id="h-the-two-phases-of-adoption" class="wp-block-heading"><strong>The Two Phases of Adoption</strong></h3>
<p><!-- /wp:heading --></p>
<p><!-- wp:paragraph --></p>
<p>Perhaps inadvertently, but we are currently transitioning through two distinct stages of industry maturity:</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:list --></p>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul class="wp-block-list"><!-- wp:list-item --></ul>
</li>
</ul>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul class="wp-block-list">
<li><strong>Phase 1: Capacity building.</strong> Market participants are laying the basic technical pipes required to send and receive Travel Rule data, at the request of the regulators.</li>
</ul>
</li>
</ul>
<p><!-- /wp:list-item --></p>
<p><!-- wp:list-item --></p>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul class="wp-block-list">
<li><strong>Phase 2: Verified payments.</strong> This is when the industry begins to <strong>instantly verify</strong> data. Under the dual pressure of regulators and market demand for safety, verification will become the default.</li>
</ul>
</li>
</ul>
<p><!-- /wp:list-item --></p>
<p><!-- /wp:list --></p>
<p><!-- wp:paragraph --></p>
<p>This will open the &#8220;Golden Era&#8221; of stablecoin payments, which will be defined by both how <b>fast</b> we can move money, but also how&nbsp;<strong>reliably </strong>we can do it. VASPs catering to the payments use case need to move beyond &#8220;check-the-box&#8221; compliance and invest in robust, two-way compliance infrastructure to win the trust of the traditional corporate world.</p>
<p><!-- /wp:paragraph --></p>								</div>
				</div>
					</div>
				</div>
				</div>
		<p>The post <a href="https://cryptoswift.eu/the-business-case-for-the-travel-rule/" data-wpel-link="internal">The Business Case for the Travel Rule</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>CryptoSwift Outpost: On-Prem Travel Rule Infrastructure for Banks and Regulated Institutions</title>
		<link>https://cryptoswift.eu/on-premises-crypto-travel-rule-infrastructure/</link>
		
		<dc:creator><![CDATA[Indrek Ulst]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 11:02:51 +0000</pubDate>
				<category><![CDATA[MiCA]]></category>
		<category><![CDATA[Travel Rule]]></category>
		<category><![CDATA[Crypto Travel Rule]]></category>
		<category><![CDATA[On-premises]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=3919</guid>

					<description><![CDATA[<p>For banks, VASPs, and other highly regulated financial institutions, the challenge is rarely just compliance. It is operationalizing compliance without creating a fragile, high-maintenance architecture around your most sensitive data. For organizations whose internal policies or regulatory interpretations require stricter control over sensitive data, this challenge becomes even more pronounced. That is the problem CryptoSwift [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/on-premises-crypto-travel-rule-infrastructure/" data-wpel-link="internal">CryptoSwift Outpost: On-Prem Travel Rule Infrastructure for Banks and Regulated Institutions</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">For banks, VASPs, and other highly regulated financial institutions, the challenge is rarely just compliance. It is operationalizing compliance without creating a fragile, high-maintenance architecture around your most sensitive data.</p>



<p class="wp-block-paragraph">For organizations whose internal policies or regulatory interpretations require stricter control over sensitive data, this challenge becomes even more pronounced.</p>



<p class="wp-block-paragraph">That is the problem CryptoSwift Outpost is designed to solve.</p>



<p class="wp-block-paragraph">CryptoSwift Outpost is a single-tenant, on-premises edge service that can be deployed when institutions need to keep Travel Rule PII within their own infrastructure, while still using the CryptoSwift platform for core transaction processing. In practice, that means sensitive customer data remains under your control within your environment and your SQL database, while CryptoSwift continues to power the transaction workflows around it.</p>



<p class="wp-block-paragraph">The result is an operating model aligned with the needs of more stringent environments: strong data control, clear deployment boundaries, and a significantly simpler system to maintain compared to heavyweight alternatives often associated with on-premise requirements.</p>



<h2 class="wp-block-heading" id="h-why-this-matters-for-regulated-entities">Why this matters for regulated entities</h2>



<p class="wp-block-paragraph">For many institutions, “cloud-enabled” is acceptable, but “cloud-only for sensitive PII” is not.</p>



<p class="wp-block-paragraph">Travel Rule data sits in one of the most sensitive categories of operational data. It includes personally identifiable information about originators and beneficiaries, and it often falls under overlapping internal security policies, data residency requirements, outsourcing controls, audit expectations, and legal review. Even where cloud use is permitted, regulated teams still want the most defensible answer to a simple question: <strong>Where does the sensitive data live</strong>?</p>



<p class="wp-block-paragraph">With Outpost, the answer is straightforward: the Travel Rule PII datastore lives on-premises, inside your environment, under your control.</p>



<p class="wp-block-paragraph">That matters because it changes the conversation with risk, compliance, security, and internal audit. Instead of asking them to accept a fully outsourced storage model for sensitive data, you can present a controlled architecture where:</p>



<ul class="wp-block-list">
<li>Outpost runs inside your infrastructure</li>



<li>the SQL database storing Travel Rule PII runs inside your infrastructure</li>



<li>the deployment is single-tenant</li>



<li>CryptoSwift handles core transaction processing, while your local environment remains the holder of the sensitive Travel Rule record</li>
</ul>



<p class="wp-block-paragraph">For regulated institutions, that is a meaningful architectural distinction.</p>



<h2 class="wp-block-heading" id="h-how-outpost-works">How Outpost works</h2>



<p class="wp-block-paragraph">Outpost sits between your internal systems and the CryptoSwift cloud API.</p>



<p class="wp-block-paragraph">Your systems integrate with Outpost as their edge endpoint. Outpost then proxies most traffic upstream, but it handles Travel Rule PII differently: it stores that data locally and links it to the corresponding transaction.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="448" src="https://cryptoswift.eu/wp-content/uploads/2026/03/image-1024x448.png" alt="" class="wp-image-3920" srcset="https://cryptoswift.eu/wp-content/uploads/2026/03/image-1024x448.png 1024w, https://cryptoswift.eu/wp-content/uploads/2026/03/image-300x131.png 300w, https://cryptoswift.eu/wp-content/uploads/2026/03/image-768x336.png 768w, https://cryptoswift.eu/wp-content/uploads/2026/03/image-1536x672.png 1536w, https://cryptoswift.eu/wp-content/uploads/2026/03/image.png 1600w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">CryptoSwift Outpost: PII data remains on-premises, while&nbsp;</p>



<h3 class="wp-block-heading" id="h-outgoing-transactions">Outgoing transactions</h3>



<p class="wp-block-paragraph">When your system submits an outgoing transaction through Outpost:</p>



<ol class="wp-block-list">
<li>Outpost receives the full transaction payload.</li>



<li>It stores the originator and beneficiary data locally in your SQL database.</li>



<li>It forwards the transaction to the CryptoSwift cloud API for transaction processing.</li>



<li>When the cloud API returns the transaction identifier, Outpost links the local PII record to that transaction.</li>



<li>If the upstream request fails, Outpost does not silently lose the local state. It marks the record as failed and preserves the operational trail.</li>
</ol>



<p class="wp-block-paragraph">That last point is important. In many integrations, error handling around sensitive side data becomes an afterthought. Outpost is designed to keep a durable local record and explicit status transitions, rather than relying on brittle happy-path assumptions.</p>



<h3 class="wp-block-heading" id="h-incoming-pii-forwarding">Incoming PII forwarding</h3>



<p class="wp-block-paragraph">For incoming Travel Rule data, the flow works in the opposite direction:</p>



<ol class="wp-block-list">
<li>CryptoSwift forwards the incoming PII payload to Outpost.</li>



<li>Outpost verifies the request signature before trusting the payload.</li>



<li>The PII is stored locally in your SQL database.</li>



<li>Outpost returns the corresponding transaction identifier.</li>
</ol>



<p class="wp-block-paragraph">This gives institutions a consistent model for both outbound and inbound Travel Rule data: local persistence, controlled linkage, and auditable handling.</p>



<h3 class="wp-block-heading" id="h-transaction-retrieval-and-enrichment">Transaction retrieval and enrichment</h3>



<p class="wp-block-paragraph">Outpost also solves a practical usability problem.</p>



<p class="wp-block-paragraph">When a client requests a transaction by ID, Outpost first fetches the transaction from the CryptoSwift cloud API. If there is a matching local PII record, Outpost injects the locally stored originator and beneficiary data into the response before returning it.</p>



<p class="wp-block-paragraph">So users and internal systems can still work with a complete transaction view, while the sensitive data remains managed locally. The cloud platform can do what it is good at, and your on-prem environment remains the source of truth for Travel Rule PII.</p>



<h2 class="wp-block-heading" id="h-what-makes-outpost-different">What makes Outpost different</h2>



<p class="wp-block-paragraph">Many on-prem solutions for regulated workloads become difficult not because the idea is wrong, but because the architecture is too large, too distributed, or too customized to operate cleanly over time.</p>



<p class="wp-block-paragraph">Outpost takes a different approach: it is intentionally small.</p>



<p class="wp-block-paragraph">At its core, the deployment model is simple:</p>



<ul class="wp-block-list">
<li>one single-tenant service</li>



<li>one SQL database</li>



<li>one clear upstream integration with the CryptoSwift cloud API</li>



<li>containerized delivery via Docker</li>



<li>environment-based runtime configuration</li>



<li>a standard health endpoint for monitoring and orchestration</li>
</ul>



<p class="wp-block-paragraph">That simplicity is not cosmetic. It is the reason Outpost is easier to maintain than many comparable on-prem offerings.</p>



<p class="wp-block-paragraph">There is no sprawling control plane to own. No large cluster of bespoke infrastructure components. No need to re-create an entire SaaS platform inside your environment just to satisfy a PII storage requirement.</p>



<p class="wp-block-paragraph">Instead, Outpost concentrates on one job: acting as the controlled local edge for sensitive Travel Rule data.</p>



<p class="wp-block-paragraph">Architecturally, it is also cleanly separated. Proxying, PII storage, transaction enrichment, configuration, logging, and persistence are split into focused components. Storage sits behind a repository abstraction, which means changes to the underlying persistence model can be made without reworking the entire service, allowing for a wide range of different database engines to be used with Outpost. Regulated deployments do not just need to launch; they need to stay supportable.</p>



<h2 class="wp-block-heading" id="h-security-by-design-not-by-marketing-language">Security by design, not by marketing language</h2>



<p class="wp-block-paragraph">Security claims only matter when they are reflected in the way the service actually behaves.</p>



<p class="wp-block-paragraph">Outpost includes several concrete controls that are especially relevant in regulated environments.</p>



<h3 class="wp-block-heading" id="h-signed-incoming-pii-forwarding">Signed incoming PII forwarding</h3>



<p class="wp-block-paragraph">Incoming PII forwarding is authenticated with HMAC-SHA256 using a dedicated shared secret. Outpost verifies the signature over the exact raw request body, not a re-serialized approximation. It also enforces a timestamp tolerance window to reduce replay risk and uses timing-safe comparison for signature validation.</p>



<p class="wp-block-paragraph">That gives institutions a clear, defensible control around cloud-to-on-prem PII forwarding.</p>



<h3 class="wp-block-heading" id="h-controlled-deployment-boundary">Controlled deployment boundary</h3>



<p class="wp-block-paragraph">Outpost is single-tenant and deployed inside the client environment. That reduces multi-tenant exposure concerns and gives infrastructure, security, and audit teams a much cleaner deployment story.</p>



<h3 class="wp-block-heading" id="h-hardened-edge-behavior">Hardened edge behavior</h3>



<p class="wp-block-paragraph">The service uses standard HTTP hardening, validates runtime configuration at startup, supports trusted reverse-proxy deployment, and exposes a straightforward health endpoint for monitoring and operational checks.</p>



<h3 class="wp-block-heading" id="h-operational-traceability">Operational traceability</h3>



<p class="wp-block-paragraph">Outpost does not treat failures as invisible side effects. It keeps explicit local record states, including pending, linked, stored, and upstream-failed conditions. For regulated operations teams, that improves observability and incident handling.</p>



<h2 class="wp-block-heading" id="h-why-banks-should-care">Why banks should care</h2>



<p class="wp-block-paragraph">Banks do not need another “flexible platform” that quietly pushes sensitive data governance into the implementation phase.</p>



<p class="wp-block-paragraph">They need infrastructure that aligns with how regulated technology decisions are actually made:</p>



<ul class="wp-block-list">
<li>keep sensitive customer data under institutional control</li>



<li>minimize architectural sprawl</li>



<li>make security controls explicit</li>



<li>preserve operational auditability</li>



<li>reduce the maintenance burden on internal engineering and infrastructure teams</li>
</ul>



<p class="wp-block-paragraph">That is where Outpost fits.</p>



<p class="wp-block-paragraph">It gives regulated institutions a pragmatic middle path. You do not have to choose between a cloud-only model for sensitive Travel Rule data and a large, expensive, custom on-prem build. You can keep the sensitive PII record on-prem, keep the deployment model simple, and still benefit from CryptoSwift’s cloud transaction processing.</p>



<h2 class="wp-block-heading" id="h-the-practical-value-of-a-smaller-architecture">The practical value of a smaller architecture</h2>



<p class="wp-block-paragraph">In highly regulated environments, maintainability is not a convenience issue. It is a risk issue.</p>



<p class="wp-block-paragraph">Every additional moving part increases the cost of patching, validating, monitoring, documenting, and defending the deployment internally. Every custom subsystem becomes another item for architecture review, another operational dependency, another audit question.</p>



<p class="wp-block-paragraph">Outpost avoids that trap by staying focused.</p>



<p class="wp-block-paragraph">It is lightweight enough to operate cleanly, structured enough to evolve safely, and opinionated enough to solve the actual regulated-data problem without dragging institutions into unnecessary platform ownership.</p>



<p class="wp-block-paragraph">For teams that need on-prem control without on-prem complexity, that difference is significant.</p>



<h2 class="wp-block-heading" id="h-conclusion">Conclusion</h2>



<p class="wp-block-paragraph">CryptoSwift Outpost is built for institutions that need a serious answer to PII control.</p>



<p class="wp-block-paragraph">It keeps Travel Rule PII anchored on-prem in the client’s own environment, while preserving integration with CryptoSwift for core transaction processing. It provides a secure, auditable, single-tenant deployment model. And because its architecture is intentionally narrow and lightweight, it is materially easier to maintain than many traditional on-prem solutions.</p>



<p class="wp-block-paragraph">For banks and other highly regulated entities, that combination is the point: stronger control over sensitive data, without inheriting a harder platform to run.</p>
<p>The post <a href="https://cryptoswift.eu/on-premises-crypto-travel-rule-infrastructure/" data-wpel-link="internal">CryptoSwift Outpost: On-Prem Travel Rule Infrastructure for Banks and Regulated Institutions</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing the CryptoSwift Rule Engine: Automating Travel Rule Compliance Decisions</title>
		<link>https://cryptoswift.eu/introducing-the-cryptoswift-rule-engine-automating-travel-rule-compliance-decisions/</link>
		
		<dc:creator><![CDATA[Indrek Ulst]]></dc:creator>
		<pubDate>Thu, 12 Mar 2026 16:18:44 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=3901</guid>

					<description><![CDATA[<p>Over the past months we’ve been shipping quite a lot of new capabilities at CryptoSwift. We introduced Travel Rule risk scoring, built a global VASP directory, integrated AML checks directly into the dashboard, improved wallet verification, and completely revamped our developer portal. Each of these improvements adds valuable signals for compliance teams operating under the [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/introducing-the-cryptoswift-rule-engine-automating-travel-rule-compliance-decisions/" data-wpel-link="internal">Introducing the CryptoSwift Rule Engine: Automating Travel Rule Compliance Decisions</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Over the past months we’ve been shipping quite a lot of new capabilities at CryptoSwift. We introduced Travel Rule risk scoring, built a global VASP directory, integrated AML checks directly into the dashboard, improved wallet verification, and completely revamped our developer portal.</p>



<p class="wp-block-paragraph">Each of these improvements adds valuable signals for compliance teams operating under the <strong>Crypto Travel Rule</strong> and regulations like <strong>FATF Recommendation #16</strong> and the <strong>EU Transfer of Funds Regulation under MiCA</strong>.</p>



<p class="wp-block-paragraph">But while building these features, one thing became increasingly obvious: all of them generate signals.</p>



<ul class="wp-block-list">
<li>Risk scores.</li>



<li>VASP information.</li>



<li>AML monitoring results.</li>



<li>Travel Rule message statuses.</li>
</ul>



<p class="wp-block-paragraph">Signals are useful, but they don’t solve the operational problem by themselves. Compliance teams still have to answer the same question over and over again:</p>



<p class="wp-block-paragraph"><strong>What should happen with this transaction?</strong></p>



<ul class="wp-block-list">
<li>Should it proceed immediately?</li>



<li>Should it be reviewed?</li>



<li>Should we wait for additional confirmation?</li>



<li>Or should the transaction be blocked entirely?</li>
</ul>



<p class="wp-block-paragraph">This is the problem the <strong>CryptoSwift Rule Engine</strong> was built to solve.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="376" src="https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-01-1024x376.png" alt="" class="wp-image-3902" srcset="https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-01-1024x376.png 1024w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-01-300x110.png 300w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-01-768x282.png 768w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-01-1536x564.png 1536w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-01.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-travel-rule-compliance-is-ultimately-a-decision-problem">Travel Rule Compliance Is Ultimately a Decision Problem</h2>



<p class="wp-block-paragraph">Many Travel Rule solutions focus on one core capability: securely sending required data between Virtual Asset Service Providers (VASPs). That messaging layer is essential for compliance, but in real-world operations it’s only the first step.</p>



<p class="wp-block-paragraph">Once a Travel Rule message is sent or received, platforms still need to evaluate several factors before deciding how to proceed.</p>



<p class="wp-block-paragraph">Typical questions compliance teams ask include:</p>



<ul class="wp-block-list">
<li>Is the counterparty VASP known and regulated?</li>



<li>What is their risk profile?</li>



<li>What does the AML monitoring system say about the wallet address?</li>



<li>Should we allow this transaction to proceed automatically?</li>
</ul>



<p class="wp-block-paragraph">Without a structured framework, these decisions often end up buried in application code or scattered across multiple systems.</p>



<p class="wp-block-paragraph">The Rule Engine introduces a cleaner approach.</p>



<h2 class="wp-block-heading" id="h-why-compliance-logic-should-not-live-in-backend-code">Why Compliance Logic Should Not Live in Backend Code</h2>



<p class="wp-block-paragraph">When crypto platforms first implement the Travel Rule, the compliance logic typically ends up hardcoded in backend services. Developers create simple conditional checks that determine whether transactions proceed or require manual review.</p>



<p class="wp-block-paragraph">It usually starts with rules like:</p>



<ul class="wp-block-list">
<li>Allow transactions from low-risk counterparties</li>



<li>Send medium-risk transactions for manual review</li>



<li>Block high-risk counterparties</li>
</ul>



<p class="wp-block-paragraph">At first, this seems perfectly reasonable. But compliance policies rarely stay static.</p>



<p class="wp-block-paragraph">Regulations evolve, risk thresholds change, internal policies adapt as teams gain operational experience.</p>



<p class="wp-block-paragraph">When compliance logic lives in code, even small policy changes require developer involvement, deployments, and testing cycles. That slows down compliance teams and introduces unnecessary operational friction.</p>



<p class="wp-block-paragraph">The CryptoSwift Rule Engine separates <strong>transaction signals</strong> from <strong>transaction decisions</strong>, allowing compliance teams to manage policies directly without relying on engineering changes.</p>



<h2 class="wp-block-heading" id="h-a-rule-engine-designed-for-travel-rule-workflows">A Rule Engine Designed for Travel Rule Workflows</h2>



<p class="wp-block-paragraph">The CryptoSwift Rule Engine acts as a decision layer on top of the data already available within the platform.</p>



<p class="wp-block-paragraph">When a Travel Rule message is created, CryptoSwift may already know several things about the transaction and the counterparty involved.</p>



<p class="wp-block-paragraph">For example:</p>



<ul class="wp-block-list">
<li>the counterparty VASP and their regulative status</li>



<li>the <strong>Travel Rule risk score</strong></li>



<li>AML risk signals from wallet monitoring</li>



<li>transaction attributes such as amount</li>



<li>the current Travel Rule message status (was it delivered, confirmed or declined?)</li>
</ul>



<p class="wp-block-paragraph">Instead of forcing developers to manually combine these inputs, the Rule Engine evaluates them automatically and determines what should happen next.</p>



<p class="wp-block-paragraph">Possible outcomes include:</p>



<ul class="wp-block-list">
<li><strong>Proceed with the transaction automatically</strong></li>



<li><strong>Pause the workflow and wait for a counterparty response</strong></li>



<li><strong>Escalate the transaction for manual compliance review</strong></li>



<li><strong>Block the transaction entirely</strong></li>
</ul>



<p class="wp-block-paragraph">The result is a clear and auditable decision process that compliance teams can configure directly in the CryptoSwift dashboard.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="537" src="https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-02-1024x537.png" alt="" class="wp-image-3903" srcset="https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-02-1024x537.png 1024w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-02-300x157.png 300w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-02-768x402.png 768w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-02-1536x805.png 1536w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-02.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-supporting-both-pre-transaction-and-post-transaction-travel-rule-flows">Supporting Both Pre-Transaction and Post-Transaction Travel Rule Flows</h2>



<p class="wp-block-paragraph">Crypto platforms typically implement the Travel Rule using one of two models.</p>



<h3 class="wp-block-heading" id="h-post-transaction-workflow">Post-Transaction Workflow</h3>



<p class="wp-block-paragraph">In this model, the blockchain transaction is executed first and the Travel Rule message is sent afterward. This is often the fastest way to become Travel Rule compliant because it requires minimal changes to existing withdrawal flows.</p>



<p class="wp-block-paragraph">Many platforms start with this approach.</p>



<h3 class="wp-block-heading" id="h-pre-transaction-workflow">Pre-Transaction Workflow</h3>



<p class="wp-block-paragraph">In a <strong>pre-transaction Travel Rule workflow</strong>, the Travel Rule message is created before the blockchain transaction is broadcast.</p>



<p class="wp-block-paragraph">This allows the platform to evaluate compliance signals first, including:</p>



<ul class="wp-block-list">
<li>counterparty VASP identification</li>



<li>Travel Rule risk score</li>



<li>AML monitoring results</li>



<li>internal compliance policies</li>
</ul>



<p class="wp-block-paragraph">The Rule Engine then determines whether the transaction should proceed or require additional checks.</p>



<p class="wp-block-paragraph">For many platforms, this enables significantly more automation and control.</p>



<h2 class="wp-block-heading" id="h-connecting-the-entire-compliance-stack">Connecting the Entire Compliance Stack</h2>



<p class="wp-block-paragraph">One of our design goals at CryptoSwift has always been to eliminate fragmentation in compliance tooling. Crypto platforms often end up using multiple systems for different parts of the compliance process:</p>



<ul class="wp-block-list">
<li>a Travel Rule messaging provider</li>



<li>a separate VASP identification database</li>



<li>AML monitoring tools</li>



<li>manual review workflows</li>
</ul>



<p class="wp-block-paragraph">These systems rarely communicate with each other in a structured way.</p>



<p class="wp-block-paragraph">The CryptoSwift Rule Engine connects these signals into a single decision framework. Risk scores, VASP directory data, AML monitoring results, and Travel Rule message information can now all feed into the same policy evaluation process.</p>



<p class="wp-block-paragraph">This approach simplifies operations and produces cleaner audit trails. When a transaction is blocked or escalated for review, the rule that triggered the decision is recorded alongside the transaction history. For compliance teams and regulators, that transparency is extremely valuable.</p>



<h2 class="wp-block-heading" id="h-automation-without-losing-compliance-oversight">Automation Without Losing Compliance Oversight</h2>



<p class="wp-block-paragraph">Automation in compliance systems always raises an understandable concern: what happens when the system makes the wrong decision?</p>



<p class="wp-block-paragraph">The Rule Engine is designed so automation can be introduced gradually. Some rules can allow low-risk transactions to proceed automatically, while others route transactions to manual review or pause workflows until additional information becomes available.</p>



<p class="wp-block-paragraph">The goal isn’t to remove human oversight, the goal is to remove unnecessary manual work.</p>



<p class="wp-block-paragraph">Most transactions are routine and predictable. Those shouldn’t require compliance officers to manually evaluate every detail. Automation allows teams to focus their attention where it actually matters.</p>



<h2 class="wp-block-heading" id="h-from-travel-rule-messaging-to-travel-rule-automation">From Travel Rule Messaging to Travel Rule Automation</h2>



<p class="wp-block-paragraph">The more we work in this space, the clearer it becomes that <strong>Travel Rule compliance is not just a messaging problem</strong>.</p>



<p class="wp-block-paragraph">It’s a decision problem.</p>



<p class="wp-block-paragraph">Who is the counterparty?<br>What is their risk profile?<br>Should the transaction proceed, wait, or be blocked?</p>



<p class="wp-block-paragraph">The CryptoSwift Rule Engine turns the growing amount of Travel Rule data into clear operational decisions that platforms can automate and audit.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="812" src="https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-03-1024x812.png" alt="" class="wp-image-3904" srcset="https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-03-1024x812.png 1024w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-03-300x238.png 300w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-03-768x609.png 768w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-03-1536x1218.png 1536w, https://cryptoswift.eu/wp-content/uploads/2026/03/rule-engine-03.png 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-available-now-in-the-cryptoswift-platform">Available Now in the CryptoSwift Platform</h2>



<p class="wp-block-paragraph">The Rule Engine is now available in the <strong>CryptoSwift Client Dashboard</strong> and fully integrated with the<a href="https://api.cryptoswift.eu/#tag/Rule-Engine" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right"> <strong>CryptoSwift API</strong><span class="wpel-icon wpel-image wpel-icon-19"></span></a> and Travel Rule workflows.</p>



<p class="wp-block-paragraph">If you’re already using CryptoSwift, you can start defining rules today. If you’re currently designing your Travel Rule implementation, our updated <strong><a href="https://dev.cryptoswift.eu/docs/workflows/rule-engine" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">Developer Portal<span class="wpel-icon wpel-image wpel-icon-19"></span></a></strong> explains how to structure both pre-transaction and post-transaction workflows using the Rule Engine.</p>



<p class="wp-block-paragraph">Our goal remains the same as always:</p>



<ul class="wp-block-list">
<li><strong>less friction for developers</strong></li>



<li><strong>more control for compliance teams</strong></li>



<li><strong>more automation where it actually helps</strong></li>
</ul>



<p class="wp-block-paragraph">And we’re just getting started.</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://cryptoswift.eu/introducing-the-cryptoswift-rule-engine-automating-travel-rule-compliance-decisions/" data-wpel-link="internal">Introducing the CryptoSwift Rule Engine: Automating Travel Rule Compliance Decisions</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>We’ve Been Busy Building again</title>
		<link>https://cryptoswift.eu/travel-rule-risk-scoring/</link>
		
		<dc:creator><![CDATA[Indrek Ulst]]></dc:creator>
		<pubDate>Sun, 15 Feb 2026 16:31:11 +0000</pubDate>
				<category><![CDATA[KYT]]></category>
		<category><![CDATA[MiCA]]></category>
		<category><![CDATA[Risk Score]]></category>
		<category><![CDATA[Self-hosted wallets]]></category>
		<category><![CDATA[Travel Rule]]></category>
		<guid isPermaLink="false">https://cryptoswift.eu/?p=3855</guid>

					<description><![CDATA[<p>The last few months at CryptoSwift have been intense in a good way. One of the most exciting developments has been our work on improving the Travel Rule risk score. Here’s What’s New at CryptoSwift. We’ve shipped a lot. Enough that I had to think twice about whether this should be one blog post or [&#8230;]</p>
<p>The post <a href="https://cryptoswift.eu/travel-rule-risk-scoring/" data-wpel-link="internal">We’ve Been Busy Building again</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">The last few months at CryptoSwift have been intense in a good way. One of the most exciting developments has been our work on improving the Travel Rule risk score. Here’s What’s New at CryptoSwift.</p>



<p class="wp-block-paragraph">We’ve shipped a lot. Enough that I had to think twice about whether this should be one blog post or three. But I’ll try to keep it structured and readable.</p>



<p class="wp-block-paragraph">As always, we build for one reason only: to make CryptoSwift the best and easiest-to-use Travel Rule solution on the market. The one that works when compliance teams and developers need it to.</p>



<p class="wp-block-paragraph">Let’s start with the biggest one.<br></p>



<h2 class="wp-block-heading" id="h-travel-rule-risk-score-real-time-risk-intelligence">Travel Rule Risk Score &#8211; Real-Time Risk Intelligence</h2>



<p class="wp-block-paragraph">We’ve added a risk score to every incoming and outgoing Travel Rule message. This might sound like a small feature, but it isn’t.</p>



<p class="wp-block-paragraph">From now on, every Travel Rule message created in CryptoSwift is enriched with a transaction risk score calculated using the AML/KYT providers we already trust internally for VASP and wallet address scoring.</p>



<p class="wp-block-paragraph">The logic is straightforward:</p>



<ul class="wp-block-list">
<li>For <strong>incoming transactions</strong>, we calculate the risk based on the originator VASP.</li>



<li>For <strong>outgoing transactions</strong>, we use the beneficiary VASP risk score.</li>



<li>If the beneficiary VASP cannot be immediately identified, we fall back to the destination wallet risk score.</li>
</ul>



<p class="wp-block-paragraph">No guessing or black magic, just structured risk assessment based on real data.</p>



<p class="wp-block-paragraph">For outgoing transactions, the risk score and severity are returned immediately when the Travel Rule message is created. This makes pre-transaction flows much more powerful.</p>



<p class="wp-block-paragraph">If you send the Travel Rule message before broadcasting the on-chain transaction, you can now decide:</p>



<ul class="wp-block-list">
<li>Do we proceed?</li>



<li>Do we mark this for manual review?</li>



<li>Do we stop it completely?</li>
</ul>



<p class="wp-block-paragraph">All before funds move.</p>



<p class="wp-block-paragraph">If you operate in a post-transaction model, the risk score still gives AML officers structured data to assess customer behaviour and keep proper audit trails. It also allows for automation, because no one wants a compliance team manually checking everything in 2026.</p>



<p class="wp-block-paragraph">For incoming transactions, the risk score is also included in the Travel Rule payload itself. That means you can automate deposit release flows. Low risk? Auto-credit. Higher risk? Escalate. Very high risk? Block and investigate.</p>



<p class="wp-block-paragraph">The risk score is available via API and inside the Client Dashboard.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="629" src="https://cryptoswift.eu/wp-content/uploads/2026/02/image-1-1024x629.png" alt="" class="wp-image-3857" srcset="https://cryptoswift.eu/wp-content/uploads/2026/02/image-1-1024x629.png 1024w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-1-300x184.png 300w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-1-768x472.png 768w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-1-1536x943.png 1536w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-1-2048x1257.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-the-vasp-directory">The VASP Directory</h2>



<p class="wp-block-paragraph">Compliance teams are constantly interested in the same questions:</p>



<p class="wp-block-paragraph">Who is this counterparty?<br>Are they regulated?<br>What jurisdictions do they operate in?<br>What’s their risk profile?</p>



<p class="wp-block-paragraph">To address these questions, we built a proper VASP Directory inside CryptoSwift. It currently contains data on over 12,000 crypto service providers globally. For each VASP, you can see:</p>



<ul class="wp-block-list">
<li>Risk score</li>



<li>MiCA compliance status</li>



<li>Countries of registration</li>



<li>Contact information</li>



<li>Whether they are part of the CryptoSwift network</li>
</ul>



<p class="wp-block-paragraph">But the important part is not the list itself. The directory is deeply integrated with the rest of our platform. When you send or receive a Travel Rule message, originator and beneficiary VASPs are automatically linked. Risk scores connect directly and everything is cross-referenced.<br></p>



<h2 class="wp-block-heading" id="h-aml-checks">AML Checks</h2>



<p class="wp-block-paragraph">On top of the Travel Rule risk score, we added full AML checks for wallet addresses and transactions inside the Client Dashboard.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="758" height="1024" src="https://cryptoswift.eu/wp-content/uploads/2026/02/image-758x1024.png" alt="" class="wp-image-3856" srcset="https://cryptoswift.eu/wp-content/uploads/2026/02/image-758x1024.png 758w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-222x300.png 222w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-768x1038.png 768w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-1137x1536.png 1137w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-1516x2048.png 1516w, https://cryptoswift.eu/wp-content/uploads/2026/02/image-scaled.png 1895w" sizes="(max-width: 758px) 100vw, 758px" /></figure>



<p class="wp-block-paragraph">You can bring your own AML provider API key if you already have a contract. Or you can obtain an AML package via CryptoSwift.</p>



<p class="wp-block-paragraph">Right now, we’re integrated with Scorechain. More providers are being added based on customer demand. If your compliance team prefers a specific vendor, tell us. We’ll integrate it.</p>



<p class="wp-block-paragraph">The goal is simple: eliminate fragmentation.</p>



<p class="wp-block-paragraph">You shouldn’t need one system for Travel Rule, another for wallet checks, and a third for VASP data. Everything should work together. In CryptoSwift, it now does.</p>



<p class="wp-block-paragraph">AML checks link directly with Travel Rule messages and the VASP directory. That means less copy-paste, fewer context switches, and cleaner audit trails.<br></p>



<h2 class="wp-block-heading" id="h-wallet-verification-more-flexible-amp-practical">Wallet Verification &#8211; More Flexible &amp; Practical</h2>



<p class="wp-block-paragraph">We’ve also significantly improved our self-hosted wallet verification widget and API.</p>



<p class="wp-block-paragraph">This includes support for video files in visual proof flows (yes, sometimes pictures aren’t enough), more customization options, on-chain testing capabilities, and improved multi-chain support.</p>



<p class="wp-block-paragraph">We strongly believe this is currently the most flexible and developer-friendly self-hosted wallet verification solution on the market.<br></p>



<h2 class="wp-block-heading" id="h-dashboard-improvements">Dashboard Improvements</h2>



<p class="wp-block-paragraph">We’ve continued polishing the Client Dashboard. Clearer layouts, better visibility of transaction risk, improved workflows.</p>



<p class="wp-block-paragraph">Compliance is already complex, the interface shouldn’t add friction.</p>



<p class="wp-block-paragraph">Small UX improvements compound over time. Fewer clicks, clearer risk indicators, faster reviews.<br></p>



<h2 class="wp-block-heading" id="h-developer-portal-2-0">Developer Portal 2.0</h2>



<p class="wp-block-paragraph">We also completely revamped our Developer Portal:</p>



<p class="wp-block-paragraph"><a href="https://dev.cryptoswift.eu" data-wpel-link="external" rel="external noopener noreferrer" class="wpel-icon-right">https://dev.cryptoswift.eu<span class="wpel-icon wpel-image wpel-icon-19"></span></a></p>



<p class="wp-block-paragraph">It’s no longer just technical API documentation. It now includes structured compliance workflow descriptions that help you design Travel Rule flows correctly from day one.</p>



<p class="wp-block-paragraph">Because the hardest part of Travel Rule implementation isn’t the API call. It’s understanding how to structure compliant flows without ruining user experience.</p>



<p class="wp-block-paragraph">We’ve documented those patterns clearly so teams don’t have to reinvent them.<br></p>



<h2 class="wp-block-heading" id="h-better-partner-support">Better Partner Support</h2>



<p class="wp-block-paragraph">Finally, we improved documentation and guides specifically for our partners: compliance companies reselling our infrastructure and other Travel Rule networks integrating with us.</p>



<p class="wp-block-paragraph">Clearer onboarding, better API documentation, faster integrations: we want our partners to succeed.<br></p>



<h2 class="wp-block-heading" id="h-why-so-much-at-once">Why So Much at Once?</h2>



<p class="wp-block-paragraph">We’ve been heads down building and prefer shipping working features over announcing roadmaps.</p>



<p class="wp-block-paragraph">Everything described here has one objective: to make CryptoSwift the best and easiest-to-use Travel Rule infrastructure provider in the market.</p>



<p class="wp-block-paragraph">➜ Less friction for developers.<br>➜ More control for compliance officers.<br>➜ More automation everywhere.</p>



<p class="wp-block-paragraph">We’re not slowing down.</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://cryptoswift.eu/travel-rule-risk-scoring/" data-wpel-link="internal">We’ve Been Busy Building again</a> appeared first on <a href="https://cryptoswift.eu" data-wpel-link="internal">CryptoSwift</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
