> For the complete documentation index, see [llms.txt](https://docs.xft.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xft.finance/idn/technical/address-facilities/xftroutingfactoryv2.md).

# XFTRoutingFactoryV2

XFT routing factory smart contracts are used for XFT Token Service TAN generation.

COUNTERPARTIES

XFTRoutingFactory [0x60AA889392144cE43AAEAb0e7215fcA034B2b354](https://sepolia.arbiscan.io/address/0x60aa889392144ce43aaeab0e7215fca034b2b354)\
XFTRoutingFactoryV2 \
VISA [0xDB9f69C2CCe2806107Fe8Df78f201664a8c16d62](https://sepolia.arbiscan.io/address/0xdb9f69c2cce2806107fe8df78f201664a8c16d62)

### Contract

FUNCTIONS

* Send debit card # + token amount to smart contract: from, to, amt
* Smart contract checks to see if debit card number exists. If no, reverts/doesnt go through
* If yes, smart contract finds the wallet address mapped to debit card number.&#x20;
* Smart contract transfers token amount from debit card wallet address 1 to debit card wallet address 2.&#x20;

***

<mark style="color:purple;">RESOURCES</mark>

Create Visa Direct business wallet given debit card number\
<https://sepolia.arbiscan.io/tx/0x472a4e6e8af6f4772d6af2a26b253508422d6fbd72cda2a5a60ad0f3b4342bac>

Prefund Visa Direct business wallet with Visa’s custom stablecoin\
<https://sepolia.arbiscan.io/tx/0x75a1d8eb7fd08358413a74b7c7ab211555081ae13dfa81c1a8c4a58fa7b5aa34>

XFT TOKEN SERVICE ABI \[contracts/XFTRoutingFactory.sol]

```json
[{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotOperator","type":"error"},{"inputs":[],"name":"WalletExists","type":"error"},{"inputs":[],"name":"WalletNotFound","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"idType","type":"string"},{"indexed":false,"internalType":"string","name":"idValue","type":"string"},{"indexed":false,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"idType","type":"string"},{"indexed":false,"internalType":"string","name":"idValue","type":"string"},{"indexed":false,"internalType":"address","name":"wallet","type":"address"}],"name":"DeployWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"idType","type":"string"},{"indexed":false,"internalType":"string","name":"idValue","type":"string"},{"indexed":false,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"inputs":[{"internalType":"string","name":"chips","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromCHIPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"cik","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromCIK","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fednow","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromFEDNOW","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fedwire","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromFEDWIRE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"iban","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromIBAN","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"lei","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromLEI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"routing","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromRouting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"swift","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromSWIFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"visa","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"burnFromVISA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"cikToWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"chips","type":"string"}],"name":"deployCHIPSWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"cik","type":"string"}],"name":"deployCIKWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fednow","type":"string"}],"name":"deployFEDNOWWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fedwire","type":"string"}],"name":"deployFEDWIREWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"iban","type":"string"}],"name":"deployIBANWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"lei","type":"string"}],"name":"deployLEIWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"routing","type":"string"}],"name":"deployRoutingWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"swift","type":"string"}],"name":"deploySWIFTWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"visa","type":"string"}],"name":"deployVISAWallet","outputs":[{"internalType":"address","name":"wallet","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"chips","type":"string"}],"name":"getCHIPSWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"cik","type":"string"}],"name":"getCIKWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"fednow","type":"string"}],"name":"getFEDNOWWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"fedwire","type":"string"}],"name":"getFEDWIREWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"iban","type":"string"}],"name":"getIBANWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"lei","type":"string"}],"name":"getLEIWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"routing","type":"string"}],"name":"getRoutingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"swift","type":"string"}],"name":"getSWIFTWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"visa","type":"string"}],"name":"getVISAWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"leiToWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"chips","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToCHIPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"cik","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToCIK","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fednow","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToFEDNOW","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fedwire","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToFEDWIRE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"iban","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToIBAN","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"lei","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToLEI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"routing","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToRouting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"swift","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToSWIFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"visa","type":"string"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mintToVISA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"chips","type":"string"}],"name":"predictCHIPS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"cik","type":"string"}],"name":"predictCIK","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"fednow","type":"string"}],"name":"predictFEDNOW","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"fedwire","type":"string"}],"name":"predictFEDWIRE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"iban","type":"string"}],"name":"predictIBAN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"lei","type":"string"}],"name":"predictLEI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"routing","type":"string"}],"name":"predictRouting","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"swift","type":"string"}],"name":"predictSWIFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"visa","type":"string"}],"name":"predictVISA","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
```

VISA DIGITAL DOLLAR ABI \[contracts/Dollar.sol]

```json
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"DollarBlockedSender","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"sharesNeeded","type":"uint256"}],"name":"DollarInsufficientBurnBalance","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"DollarInvalidBlockedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"DollarInvalidBurnSender","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"DollarInvalidMintReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"rewardMultiplier","type":"uint256"}],"name":"DollarInvalidRewardMultiplier","type":"error"},{"inputs":[],"name":"DollarPausedTransfers","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"sharesNeeded","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"name":"ERC2612ExpiredDeadline","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"ERC2612InvalidSignature","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"AccountBlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"AccountUnblocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"}],"name":"RewardMultiplier","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"BLOCKLIST_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardMultiplierIncrement","type":"uint256"}],"name":"addRewardMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"blockAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"convertToDollars","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isBlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardMultiplier","type":"uint256"}],"name":"setRewardMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"sharesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDollars","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"unblockAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]
```

XFT TOKEN SERVICE V2 CONTRACT \[contracts/XFTRoutingFactoryV2.sol]

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

interface IERC20 {
    function mint(address to, uint256 amount) external;
    function burn(address from, uint256 amount) external;
    function transfer(address to, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
}

contract RoutingWallet {
    address public factory;
    address public owner;

    event WalletTransfer(address indexed token, address indexed to, uint256 amount);

    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }

    constructor(address _owner) {
        factory = msg.sender;
        owner = _owner;
    }

    function transfer(address token, address to, uint256 amount) external onlyOwner {
        require(IERC20(token).transfer(to, amount), "transfer failed");
        emit WalletTransfer(token, to, amount);
    }

    function balance(address token) external view returns (uint256) {
        return IERC20(token).balanceOf(address(this));
    }
}

contract XFTRoutingFactoryV2 {
    IERC20 public immutable token;
    address public operator;

    mapping(bytes32 => address) private routingToWallet;
    mapping(bytes32 => address) private ibanToWallet;
    mapping(bytes32 => address) private swiftToWallet;
    mapping(bytes32 => address) public cikToWallet;
    mapping(bytes32 => address) public leiToWallet;
    mapping(bytes32 => address) private fedNowToWallet;
    mapping(bytes32 => address) private fedwireToWallet;
    mapping(bytes32 => address) private chipsToWallet;
    mapping(bytes32 => address) private visaToWallet;

    event DeployWallet(string idType, string idValue, address wallet);
    event Mint(string idType, string idValue, address wallet, uint256 amount);
    event Burn(string idType, string idValue, address wallet, uint256 amount);

    error NotOperator();
    error WalletExists();
    error WalletNotFound();

    modifier onlyOp() {
        if (msg.sender != operator) revert NotOperator();
        _;
    }

    constructor(address _token) {
        token = IERC20(_token);
        operator = msg.sender;
    }

    function _salt(string memory id) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(id));
    }

    function _predict(bytes32 salt) internal view returns (address) {
        return address(uint160(uint256(keccak256(
            abi.encodePacked(
                bytes1(0xff),
                address(this),
                salt,
                keccak256(abi.encodePacked(type(RoutingWallet).creationCode, abi.encode(operator)))
            )
        ))));
    }

    // ---------------- ROUTING ----------------
    function predictRouting(string memory routing) public view returns (address) {
        return _predict(_salt(routing));
    }
    function deployRoutingWallet(string memory routing) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(routing);
        if (routingToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        routingToWallet[salt] = wallet;
        emit DeployWallet("ROUTING", routing, wallet);
    }
    function mintToRouting(string memory routing, uint256 amt) external onlyOp {
        bytes32 salt = _salt(routing);
        address wallet = routingToWallet[salt];
        if (wallet == address(0)) wallet = deployRoutingWallet(routing);
        token.mint(wallet, amt);
        emit Mint("ROUTING", routing, wallet, amt);
    }
    function burnFromRouting(string memory routing, uint256 amt) external onlyOp {
        address wallet = routingToWallet[_salt(routing)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("ROUTING", routing, wallet, amt);
    }
    function getRoutingWallet(string memory routing) external view returns (address) {
        return routingToWallet[_salt(routing)];
    }

    // ---------------- IBAN ----------------
    function predictIBAN(string memory iban) public view returns (address) {
        return _predict(_salt(iban));
    }
    function deployIBANWallet(string memory iban) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(iban);
        if (ibanToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        ibanToWallet[salt] = wallet;
        emit DeployWallet("IBAN", iban, wallet);
    }
    function mintToIBAN(string memory iban, uint256 amt) external onlyOp {
        bytes32 salt = _salt(iban);
        address wallet = ibanToWallet[salt];
        if (wallet == address(0)) wallet = deployIBANWallet(iban);
        token.mint(wallet, amt);
        emit Mint("IBAN", iban, wallet, amt);
    }
    function burnFromIBAN(string memory iban, uint256 amt) external onlyOp {
        address wallet = ibanToWallet[_salt(iban)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("IBAN", iban, wallet, amt);
    }
    function getIBANWallet(string memory iban) external view returns (address) {
        return ibanToWallet[_salt(iban)];
    }

    // ---------------- SWIFT/BIC ----------------
    function predictSWIFT(string memory swift) public view returns (address) {
        return _predict(_salt(swift));
    }
    function deploySWIFTWallet(string memory swift) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(swift);
        if (swiftToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        swiftToWallet[salt] = wallet;
        emit DeployWallet("SWIFT", swift, wallet);
    }
    function mintToSWIFT(string memory swift, uint256 amt) external onlyOp {
        bytes32 salt = _salt(swift);
        address wallet = swiftToWallet[salt];
        if (wallet == address(0)) wallet = deploySWIFTWallet(swift);
        token.mint(wallet, amt);
        emit Mint("SWIFT", swift, wallet, amt);
    }
    function burnFromSWIFT(string memory swift, uint256 amt) external onlyOp {
        address wallet = swiftToWallet[_salt(swift)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("SWIFT", swift, wallet, amt);
    }
    function getSWIFTWallet(string memory swift) external view returns (address) {
        return swiftToWallet[_salt(swift)];
    }

    // ---------------- CIK ----------------
    function predictCIK(string memory cik) public view returns (address) {
        return _predict(_salt(cik));
    }
    function deployCIKWallet(string memory cik) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(cik);
        if (cikToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        cikToWallet[salt] = wallet;
        emit DeployWallet("CIK", cik, wallet);
    }
    function mintToCIK(string memory cik, uint256 amt) external onlyOp {
        bytes32 salt = _salt(cik);
        address wallet = cikToWallet[salt];
        if (wallet == address(0)) wallet = deployCIKWallet(cik);
        token.mint(wallet, amt);
        emit Mint("CIK", cik, wallet, amt);
    }
    function burnFromCIK(string memory cik, uint256 amt) external onlyOp {
        address wallet = cikToWallet[_salt(cik)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("CIK", cik, wallet, amt);
    }
    function getCIKWallet(string memory cik) external view returns (address) {
        return cikToWallet[_salt(cik)];
    }

    // ---------------- LEI ----------------
    function predictLEI(string memory lei) public view returns (address) {
        return _predict(_salt(lei));
    }
    function deployLEIWallet(string memory lei) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(lei);
        if (leiToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        leiToWallet[salt] = wallet;
        emit DeployWallet("LEI", lei, wallet);
    }
    function mintToLEI(string memory lei, uint256 amt) external onlyOp {
        bytes32 salt = _salt(lei);
        address wallet = leiToWallet[salt];
        if (wallet == address(0)) wallet = deployLEIWallet(lei);
        token.mint(wallet, amt);
        emit Mint("LEI", lei, wallet, amt);
    }
    function burnFromLEI(string memory lei, uint256 amt) external onlyOp {
        address wallet = leiToWallet[_salt(lei)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("LEI", lei, wallet, amt);
    }
    function getLEIWallet(string memory lei) external view returns (address) {
        return leiToWallet[_salt(lei)];
    }

    // ---------------- FEDNOW ----------------
    function predictFEDNOW(string memory fednow) public view returns (address) {
        return _predict(_salt(fednow));
    }
    function deployFEDNOWWallet(string memory fednow) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(fednow);
        if (fedNowToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        fedNowToWallet[salt] = wallet;
        emit DeployWallet("FEDNOW", fednow, wallet);
    }
    function mintToFEDNOW(string memory fednow, uint256 amt) external onlyOp {
        bytes32 salt = _salt(fednow);
        address wallet = fedNowToWallet[salt];
        if (wallet == address(0)) wallet = deployFEDNOWWallet(fednow);
        token.mint(wallet, amt);
        emit Mint("FEDNOW", fednow, wallet, amt);
    }
    function burnFromFEDNOW(string memory fednow, uint256 amt) external onlyOp {
        address wallet = fedNowToWallet[_salt(fednow)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("FEDNOW", fednow, wallet, amt);
    }
    function getFEDNOWWallet(string memory fednow) external view returns (address) {
        return fedNowToWallet[_salt(fednow)];
    }

    // ---------------- FEDWIRE ----------------
    function predictFEDWIRE(string memory fedwire) public view returns (address) {
        return _predict(_salt(fedwire));
    }
    function deployFEDWIREWallet(string memory fedwire) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(fedwire);
        if (fedwireToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        fedwireToWallet[salt] = wallet;
        emit DeployWallet("FEDWIRE", fedwire, wallet);
    }
    function mintToFEDWIRE(string memory fedwire, uint256 amt) external onlyOp {
        bytes32 salt = _salt(fedwire);
        address wallet = fedwireToWallet[salt];
        if (wallet == address(0)) wallet = deployFEDWIREWallet(fedwire);
        token.mint(wallet, amt);
        emit Mint("FEDWIRE", fedwire, wallet, amt);
    }
    function burnFromFEDWIRE(string memory fedwire, uint256 amt) external onlyOp {
        address wallet = fedwireToWallet[_salt(fedwire)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("FEDWIRE", fedwire, wallet, amt);
    }
    function getFEDWIREWallet(string memory fedwire) external view returns (address) {
        return fedwireToWallet[_salt(fedwire)];
    }

    // ---------------- CHIPS ----------------
    function predictCHIPS(string memory chips) public view returns (address) {
        return _predict(_salt(chips));
    }
    function deployCHIPSWallet(string memory chips) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(chips);
        if (chipsToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        chipsToWallet[salt] = wallet;
        emit DeployWallet("CHIPS", chips, wallet);
    }
    function mintToCHIPS(string memory chips, uint256 amt) external onlyOp {
        bytes32 salt = _salt(chips);
        address wallet = chipsToWallet[salt];
        if (wallet == address(0)) wallet = deployCHIPSWallet(chips);
        token.mint(wallet, amt);
        emit Mint("CHIPS", chips, wallet, amt);
    }
    function burnFromCHIPS(string memory chips, uint256 amt) external onlyOp {
        address wallet = chipsToWallet[_salt(chips)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("CHIPS", chips, wallet, amt);
    }
    function getCHIPSWallet(string memory chips) external view returns (address) {
        return chipsToWallet[_salt(chips)];
    }

    // ---------------- VISA ----------------
    function predictVISA(string memory visa) public view returns (address) {
        return _predict(_salt(visa));
    }
    function deployVISAWallet(string memory visa) public onlyOp returns (address wallet) {
        bytes32 salt = _salt(visa);
        if (visaToWallet[salt] != address(0)) revert WalletExists();
        wallet = address(new RoutingWallet{salt: salt}(operator));
        visaToWallet[salt] = wallet;
        emit DeployWallet("VISA", visa, wallet);
    }
    function mintToVISA(string memory visa, uint256 amt) external onlyOp {
        bytes32 salt = _salt(visa);
        address wallet = visaToWallet[salt];
        if (wallet == address(0)) wallet = deployVISAWallet(visa);
        token.mint(wallet, amt);
        emit Mint("VISA", visa, wallet, amt);
    }
    function burnFromVISA(string memory visa, uint256 amt) external onlyOp {
        address wallet = visaToWallet[_salt(visa)];
        if (wallet == address(0)) revert WalletNotFound();
        token.burn(wallet, amt);
        emit Burn("VISA", visa, wallet, amt);
    }
    function getVISAWallet(string memory visa) external view returns (address) {
        return visaToWallet[_salt(visa)];
    }

}

```
