diff --git a/__tests__/__fixtures__/sample_txs.ts b/__tests__/__fixtures__/sample_txs.ts index 88b5be820..8d13fed14 100644 --- a/__tests__/__fixtures__/sample_txs.ts +++ b/__tests__/__fixtures__/sample_txs.ts @@ -4,6 +4,8 @@ export const nftCreationTx = { weight: 8.000001, timestamp: 1656543561, is_voided: false, + signalBits: 0, + nonce: 0, inputs: [ { value: 100n, diff --git a/__tests__/__mock_helpers__/get-token.mock.ts b/__tests__/__mock_helpers__/get-token.mock.ts new file mode 100644 index 000000000..0ce4b5efb --- /dev/null +++ b/__tests__/__mock_helpers__/get-token.mock.ts @@ -0,0 +1,41 @@ +import { NATIVE_TOKEN_UID } from '../../src/constants'; +import { TokenVersion, ITokenData, ITokenMetadata } from '../../src/types'; + +export const mockGetToken = async ( + tokenUid: string +): Promise> => { + const tokenMap: Record = { + [NATIVE_TOKEN_UID]: { + version: TokenVersion.NATIVE, + uid: NATIVE_TOKEN_UID, + symbol: 'HTR', + name: 'Hathor', + }, + '01': { + version: TokenVersion.DEPOSIT, + uid: '01', + symbol: 'TKN01', + name: 'Token 01', + }, + '02': { + version: TokenVersion.FEE, + uid: '02', + symbol: 'FBT', + name: 'Fee Based Token', + }, + dbt: { + version: TokenVersion.DEPOSIT, + uid: 'dbt', + symbol: 'DBT', + name: 'Deposit Based Token', + }, + fbt: { + version: TokenVersion.FEE, + uid: 'fbt', + symbol: 'FBT', + name: 'Fee Based Token', + }, + }; + + return tokenMap[tokenUid]; +}; diff --git a/__tests__/integration/configuration/docker-compose.yml b/__tests__/integration/configuration/docker-compose.yml index d2244d260..43cbe34f5 100644 --- a/__tests__/integration/configuration/docker-compose.yml +++ b/__tests__/integration/configuration/docker-compose.yml @@ -8,7 +8,7 @@ services: fullnode: image: - ${HATHOR_LIB_INTEGRATION_TESTS_FULLNODE_IMAGE:-hathornetwork/hathor-core:v0.67.0} + ${HATHOR_LIB_INTEGRATION_TESTS_FULLNODE_IMAGE:-hathornetwork/hathor-core:experimental-push_fee_header} command: [ "run_node", "--listen", "tcp:40404", @@ -40,6 +40,7 @@ services: retries: 10 tx-mining-service: + platform: linux/amd64 image: ${HATHOR_LIB_INTEGRATION_TESTS_TXMINING_IMAGE:-hathornetwork/tx-mining-service} depends_on: diff --git a/__tests__/integration/configuration/precalculated-wallets.json b/__tests__/integration/configuration/precalculated-wallets.json index 92a9296eb..e8cfb6174 100644 --- a/__tests__/integration/configuration/precalculated-wallets.json +++ b/__tests__/integration/configuration/precalculated-wallets.json @@ -1,102 +1,152 @@ [ -{"isUsed":false,"words":"waste edit random program emotion vapor people scheme axis phone peasant end real tired panther build subject pyramid ceiling glory nature proud monitor empower","addresses":["WYLW8ujPemSuLJwbeNvvH6y7nakaJ6cEwT","WUfmqHWQZWn7aodAFadwmSDfh2QaUUgCRJ","Wi8zvxdXHjaUVAoCJf52t3WovTZYcU9aX6","WSu4PZVu6cvi3aejtG8w7bomVmg77DtqYt","WVbN5f2vS4TyP2XmS2x8aG2Qc5oACy3e7L","WY6wbpDWE1EFHpKzaknp9hMSrhZiH5jJ9s","WXQs68APxW9VTpbjK9FBMWrwWidxTwZpoN","WeWod5pie133e6DW3PRjhsXDp4Yq6d2D9a","Waf7MEhFy6ibcrA4sCKuKidEcW9p7E7C48","WXzfjqxKqe44yLfrsx3bmbXFRehhEgUofC","WfWFSZYyAaGTEDuLyMPAdotLuiMhkDUkyS","Wg7BaqXikZBDQcWipgauMSR38qAvsUVZvy","WhFKDjgBRScAqZHfc1XvWHj3nwVAgUvuUf","Wjos8haw4WnqkK2KauC19Xb53XLFzx5bB5","Wf5ivZqY6Ky7rp1MTPvWn2TgXgykYMos6x","WQ3YUhdLtL3D1RZvj1wGz2BSGW1bM9Wj12","WXfhSWZYaEQbkWAjFJF7bBjYtv8jHavYC6","WYd8CMafF44mnVZUBZrdPqcNFFVhCm737s","Wg7wUVBBuAKenAa6FWBi9pJAE83rHmvSzQ","WPm5JsTnYyuWQfpwRStDRshJb7X4XXPih3","Wgop7ug1pTDJhhUVMzAUTEznzRRLEdzAGr","WcRom2aEeLkcQMmiv1myTLZRG1Q6G6htEJ"]}, -{"isUsed":false,"words":"reject broccoli biology float day vendor soldier dust monster glimpse satisfy beyond cheese stool quit crisp hungry inmate frost young purity episode crowd bag","addresses":["WdNBvoPdTnrwxGHrx5AzdGe3tpGaVa2yEA","WRehHVaRiCXK2dWYo68m9pY27gg4bTx73A","WfhE2AoCLwgTS6JPALS1JbgMKW3S8G6pae","WPwP8JsuBLaWh6b2nQJYzo5MWFoZKhgRhU","WQL8bexsj4NK5gN218W5TUcCSsi9md55NM","Wd9U4VoteprXZWrfH35NGjqmqkMT1QvFHh","WbvKfSpK2TFpEe6VQH6auE4PfJuC9Cvp7U","Wj2oVDHS9ZdjXCrrpoNcbkszR8RmZeUq3W","WZFiKW88jvBWKNPJRh3Rr5LD57h2BGaX87","WXCDEtB91nu3zqAWhGc1dKz7ofdQX3Ct1F","WPXz47JyVt8oPQJLDqY45opwFkKNDieTki","WPBXusEYEejN2oMiciJztaRnaHwP4EysAT","Wa3knJh8wjygWBKpnN3p7STMS7SBiMaDCW","WX2dm6zhVqaitCpjsiEaa21RFhBohhMiFs","Wdw3q7Zw25qr3b6daCWBMjsqzDWadFt8fN","WdsvSeqTEwqzmywvH8DMWdvEZkBRBMEHjV","WXbB7TsDcWU2wgGQxm5Qmax73N8is3Ruqi","WevAunqgWrQcRQtLG4uZjgLwg8fg92GVzr","WevyhKuVhKKHYVtERGpQDrxTfnXcpx82Pj","WVtYFVMNbVLhCgoqydusrPDUu8RUXTVYUx","WZxVfTw99ZCNbFr6wiuappYoBd7vfbMJL9","WagRZ8MX6M2uLi2ZHGtG9tBP3vKjbMXe6R"]}, -{"isUsed":false,"words":"kangaroo lava certain anchor ahead injury orange vital maid toddler tip bracket emotion police major lamp whip rib weapon relief devote conduct raw host","addresses":["WjQeyVDYh1rBg3mKqM821UjoFSy9mqMikn","WfixxnKunWsy3FS7a2PRiYqcxzcMvuu57q","Wg8fnfh7TyUR5G99LAf615n8Tq662VTqyu","WU9MPQkZd5GVbJsRKS5LRQz5gyQ814gsvL","Waspov5y7UDiz3cNisfF39D5QyMYxhstKs","Wd6Qnzcav8JHj8SMYTo8amv7aA6qoqs6Ly","WQUMB4srmyLjBraDYGy7aGo4DxnrtFqRH7","WPkHwf8Q2GLrbn5pXozF4y5hVbCFnzugd4","WgeLCHeKNNwQKkpEN4J7MouctVupxbjTrG","WgBHYjYRnej7zGp7ws9XLYpTEPPPDrQpdu","Wer63MPuKqWZumA13UFkqngJaALsJEBC21","WmVZE9rP1gJw7av7ehYZJ1gSCShmo117Rw","We9spEjjHPVEZYczWgLFxieDw9schkRBgp","WjHBz7P5XcMMy5jt1vQWuw78JRf2XfqVr6","Whc8bLYRB6xktvY7qKgUZVC7t7SVPnr5MA","WhkQLzXddPrefuaPp55pqG4FhcgTeGzvWG","WkL3egPfRaTW75mQQ7R3T2CztKsKK5FrJh","WW5NVCRKbTEK9C6x5RXFzHZiGBvS5L7XWk","Wd5XwBE6MeJNjfg8cYo54MMa7B8zqm6UAS","WRr8GC3V3Qp5EF5G8bS1GsLoKmW9T1nEvA","WUjWugHoYCdZZV4jVFT7ofZzhaXa3u7mLt","WZLrqdHbHDqaKQgMiGtkHXfAMxYgMyEtzh"]}, -{"isUsed":false,"words":"wave smoke invest local upper desert truck upon harsh disease just bamboo deputy zone village fashion metal essence human flee satoshi brain genre miss","addresses":["WYWzxEa8Ugc7dz13owshdWZBWRkaU4ePsi","WgC5RzWL8piv46EzekAuo8jqDhJhGoGeJP","WXdk7Brze6xyGMeShA4xektN1KVxc2aby8","WXdjtgP32vNGSPvkaj8PsQMwB8f1znbjRR","WbZBQzShCGcqgDziQZNnnF6tYY3Vc1iZM2","WV6mXrc5BxtzZohB5S8Dy7S9XW8qCMzSZj","WjUNkDDm2hEHQHU1MV6gmYxNh6aYraXxdt","WQ7P1FK31UP9pCbhpdrNyfUfxrLaC8BeKk","WcbbV3MweWhM4RdFU8WBaFGqsK5o1uhGJM","WcNXiZFCZRCBkaR14xWRixKjPat2CHF3FQ","WQ7qkMBiWfynvDm1aEsJiX2krpJRdrZ8h7","Wb88k7Fvdq1BRQE5WCBeBmM66hUHzHM938","WXTvAKjj5vjfonoFwmR14jEpWuV4AmYh61","WhnJriDrVWUFc3UomsrMFHduhnzb7JMZ7s","WdcvxzkR7EgSYHGpYCjG5suY6f6CvJqzRu","WTgrnqZWuUKA1ZvSSgb3Xc2CBWNGQtiyst","WWFjTo8eJaJE6Xmmf7x9snPHpJRKNEqNaH","WRSbPKj9xrHYGvKzLDfMjkeDqtW6XXdc9p","WPq7nBZEXpf2KwmZahgx7U2ZtYTV1fKrzr","WaagNTiiLAsapHGQDtcLgtqRRCdRcZyTFv","WSYti8fj7ooPYjorLJ8HHy4nzeGK213nor","WYQrLC9z1rH4jJGjYr8tUoVDQkgKhLTMd1"]}, -{"isUsed":false,"words":"river hand marriage spread child type code shrug ancient viable arrow amount sustain loan wreck neglect moral belt mail secret pipe imitate axis bright","addresses":["WkrgwtEadkrvPG8MkcXJx19SeAauHeada8","Wi8mQSnvvu7ixatW8wuFF6ja1uT4eAzNS7","WX9p1dxXvqjM9cGm6guccN2DJ8fccqdgMf","WmPDfiRCbzhs3Jg6JgXD6SXekkpxYNFkXA","Wj2KmFK65wgxHG2V8Lwkhrcz3Gtuc27M7j","WbDdL3hj8iXR3xBVeMSZmsRkDKu4z8mXTM","WeGFrXf5r6vxQ17vgEDVVu25iSErXSsH4a","WhCkKdjGrxxJ8D31mRxgffpHtzAzNgMKGG","WUnMNU3tS2zsU65AUj555L1Qnbn95sDK7r","WdPvK7wiYgcy9UkeXFLXpCCRsEkXucYtcJ","WYBxaLghYNeb2YwUDqjyKyMcQkH9fP8yPC","WSnojZd9maD1vfrp1v2xJUWPchEPJCeCno","WWH2ctb82KPYxAfZTXrvkHKiCWik1Tipbw","WfWLx5jAFiJJXfgQW3QXsTZMZoJjzYCwY1","WgDR4JtnPqK6ggwrSJaMBFCUr4B9nbtoMQ","WZmn2zSEaGHAJW13D83Eurb9dQfJXCctCZ","WPc7v2t1FuErACLRW88oGRtAhmKEWrs5wd","WWzVHKvnfU4WC64gWTDYdcoq2tWzr6jAXt","WPKmhYmABaVA5U8DZB39WznZTnK2DH7EZ2","WXRUpNhuTPBR7yoimvr4dQNVepg4VPyfUZ","WdjCDvPcmY8w5oW7Phpqsr8TCGZnKafaPb","WabGXkziG6ty6rsJKbeB83JDv6CkXRJcgC"]}, -{"isUsed":false,"words":"green obscure chef inhale shield fine hair hand token annual online mutual crane moment heart quick car inspire wrap kitchen guitar title pepper leader","addresses":["WY3Xi1P5EGbkJj2eEJoEWG6wcV4L2EHday","WciK2U6LEozKuF53vAE5US4wix71oU8Tmj","WgBqquwx7BMhiBsUN2JopZM9qpRuf2vb1m","WQGupxUMdCTaWNCob1D4DneaDoYGv48r9g","WiamvQtGmxUJ8RBactBDns8cseEmMDnhyM","WgnVPnAPbagYVF5tuZkHYuStA8NgTMPXRU","WPPbwFk6mpaiNyKV2FPjNG4GzamgYE6VkU","WNmpxhck4B5KpWZL1CY3Pe78ACZ96Q1rbF","WTyjLouACt3hDkASWHu4MRiL9icFEuepyF","Wezt4zLDkL2q4u2hSNkNf6iWyxTiFajomm","WRGV9GFbPQ9CMu34HPL4uBPd93TM8PF1qF","WdsKLd8YZtB4R4Wsou1AJEBzsshCMFr9Ks","WYubXXKjaoMsPeodaqTRsBByBMFmEvomRP","WRoTV2w9LR8gCwFSL1aP8SEyDjzgrQSjy5","WSZfZGXFrPZqBND1Tg6AgU7WsLf56SSX9k","WPrX24yPXGRr7VtWAzAdw4EStpqfVqPDJk","WdY5cMxrFxTodi842oEiARiMKpfDo2LqoR","WkUeQZtBfaUnw55Lh2YJU21hYajhPbYYeR","WgMtXpSAZuAPsV8eYS2kWoWXSYuF8URCq1","WeXtQLDMC2t2tUTsix2GDyjSHw5jRhvRkN","WRMisSPe5vn9ao9mgQvEQwcDFcMFqdwYdx","WRwz3RQ1q9ex8GZLChNXjsrdh89ck41vLW"]}, -{"isUsed":false,"words":"catch swim dry leopard address vessel dilemma music birth car forward vivid october front raise camera juice farm error twice until asset rare cruise","addresses":["Wh3XcT5Ek8PPWmQVP6ezy9ENqw1Er4uYpY","WiDCLtKR7PsnRu8E8nGKwU5LvYAr5iTxV5","WXJtt1R726u3W5J6WAc2iHU7Yz31NaR6eY","WcdFTL7A3RjWdgJHrdJvD6dXXiKrXs9djV","WaCUa76vLwPiD9UHGKMCaEpTMYsDcVHqia","WZmrVifZNRW7W1JS9NQCiML7SbaAHh8dG7","WiEQXqCAj6zbEhro8UFwybHnJymdJatwwe","Wfue9SB8X38WtnwXXrxisGSMjttSRvzL4X","WSMvBbjVXpTfsWmDkb1PFmxWX74vRpRTgP","WPWWoQpzjNAp2GsUF45dtDXuXpCSSuWwzV","WkLSqNufD3BmVVy2zGfy4dRbU69aNdMm6N","WcRghpJVF2NdVFEELSa6EAJ1W6HphctmFQ","WRvFAsB5W9XFwFFcDHSTVGXNbriQKkRB6d","Wa1UW289KQb2SGMwwZdTPpd7Ev1xXhU6mw","WZZM4hYC9Tpndq4vfrgf6S9spWEVux4rjd","We9qWcBfg5MecuqhSYpypFp1tDScEciXzL","WZPEsn38NaWLb33onKmPH9q5yzUbYVMhW9","WYrt2qCwSQxPUheULEyq8soPVfFhNzyF9N","WYCg7L1M9u79QZ56vFGkZY9eWKEFHWGc9p","WWqtkaPtTmBti7Su2U8EaT8hECMLaJT4Kg","WUuLm98CXik6yFoBiZxx89L9cnebvvUJrz","WZzmmJx5zfSicQtr6eL6oywt1cNqidMK1v"]}, -{"isUsed":false,"words":"convince speak skirt glide potato faint one shift elder copy leisure slight page social obvious forget nephew cook sock inmate fossil usage receive true","addresses":["WWDZF7ehCR7Je2Pw7AYBHth9q1icgbr74f","WhqZE7gVNQ65BsvwTehvURpY9iyS9Q9sJY","WiWypUgxf6BhcqPAa95Jmemdqae8NAESfB","Wh6ypwpDMCLuyk7sU2E3DuRRQ7jSEntpuZ","WPcisPANtMubGpWhmupMLsSvFSoxQFd4ry","WgesT6yr2PXanUEoiYLPA7ap22UrCFrhfx","WXpVYjZxtNAue4QVpTdyAuyS9FHECVHvb6","WYe5gv196hW8BJZknizgj2ft8TP9K99wPh","WQxeUqXDKPhAAW9JsDAXnW6ozRvkezn6mq","WZLkrNV2J1r62A9LRQNy2TVwVM4Vyg4sgg","WgNUmVqJfFLzswRAopbmfxJvvAyu7FjNtL","WZ9CV82M8YHJ5KkM5YW9VZxFZrFQGzfECk","We5xSNE3Kt6cNbDyxGG8sTfV2NHyxrVeYf","WZGX3RCabdJeGkWnAeBMfMewpdJxQneAbd","WchCgdHqLFLw5QgADj4wkr18nS1Qei7Pe6","WcM3Qm3VfSpyiuxKunxXSiU6Un7dVLJoEx","WfAz1cn6xQKk7v7TtutqHuGdxVM4SiFzfh","WkjBnNGJDSCKohgdoJ1xY6P45vcnBQBKKY","WRgerx7R6FneBfMi8RNFWy4KKjPmyepXr7","WUQgnpJ51Mh7baPGCvSkctyrtaVzMqUMhu","Wd1SFp4oPoTc6oS73PVsAh6S1uDdk6wgVn","WZWhbPTC23usfKX9Pwmpw3DUdqjX5q1qRU"]}, -{"isUsed":false,"words":"wire promote task coin gym rebel comfort mountain high axis fossil table topic universe suggest ship milk essence often crash bless speed wave person","addresses":["WiatYw5uH1Ls9NCFFdvmsaHkaUQzCR5Y9h","WipmDMuVv2rJGTLvQbxPh2vJUNrRQ9tL67","WdBWobhzj2mSaXvzKWrMHRt8EsSCtCDhMP","WX8bpk3idngzS5XnmVdqmDz4c4JLauQSrp","WQLEiN6z5Z8z74vRu64QpMc3HJHxMpRGKE","WQBG8zcyu4juJVaamMGowet7SDeyXoZ3VT","WcC6zLXoePwBif4JwWhpnda6ixGNYHS4xB","WZ2aAhLXhiYHTvLPaQx12UjX8UzNvdgH3R","Wk2T7bLbGsQSZRjuksBm2qmgKbPt96PhEN","WS3pjmgas7frmVEDXEALJwKhN1yq5TjJAr","Wao1rNZ6NykKreiHvfi39onfYkCXa2ez9K","WWyCgUaXcSqaei2VDYhPnv5sSjhZa1cV3U","WVeB671e449KZYyF3SBM3vJLFLej2GMBbK","WPRskdVRfXVzbwQmZboKdnAug5RcqDn1VJ","WQf8WYv44sRDJjNyfdacyBSMKGKoJEcEm8","WbDCWZKh9yQAG1r8sBgjMxsURrcPEajNrc","WjpeEQSt2kdT7qVcY7pcwkYDNgDFYKmZqL","Wa3u5Kn817zPkzK9dXxdmyom8WBY5RXeva","WmMGfqeV715Sdjn9dXKGd2iFLfNoJr7Zi7","Wbk4zjk1MCZe5uBDdrUtwST6fh7q3Kcq2B","WVqNwb2Qepo7p231mR9ZPWnBP1BBET44Gr","WjxrPQo23q8aqpGCdZqqJfmLj5tfFeJxED"]}, -{"isUsed":false,"words":"point scissors more whisper sick act border husband reunion pact advice income yellow polar theme bargain puppy blame car lunar top rail tornado phone","addresses":["WRm6XnLThmafALPhXnpWWeBCvJCZaodiQc","WgNc6VonvEJ98TMeS2FwM6AMsP6xioAT4M","WgSkXRHYfiKbCjK5DwSmf3Kuwv7a5aQaUr","WWdAQ5ZDbFgfuSSpVZ7eWUCLxh4WKTt7W3","WegwcWL8X7PkpWJzkEpbq3NJemuUpg2RvL","Whi1nk479FHpHeuxsSwYmLBdSKhfVSfnWW","WXaqC9ZyNGNNAxTqtn1FUYDH5bsyUMiFpD","WWU8267xaaMLqYzXs2jnxJ8DzuEAHnw8oZ","WgkJQDL8ZnTGL2j22E7GoZV9DRCfV3umci","WRSDxvz5pGZBc9ByEf2yJw1DAZdzLnkoee","Wc38Lgw49sJXB5HyyX2PKwSeU9QyVw9dU8","WjJuuBs574q7d5ykDSWV8thvE9mpaRcD5o","WXy47FqK63U3AKH1BjC5eHQUBM5k8gnGyU","WiPkniPtCwWFwzuVn24Zd2LdnRjjB4wobs","WTpbKAfSFHTtv46fR3cw4iCuPpdAXSmTan","WW9htJS23rirqcTgiUQnsgeHMc21GxTykU","WaW4SuqAqwiFuRjggk9WFzKjCCjdZitWtE","WgEJ7SRgp4HiwFNNKGLtNazLrsNYvwrH5K","WUp5k2H4FPmBJAhwMWKr7n7u7Say9AAQs1","WZKnYKESB1z4EmxtEYQTkKDHwJtey2ifx2","WeUDGacfAz2f3kDtVukT3HXJQkzKDcjLbU","Waw8gzcpuc87mDTTmBBX8M6N1TLou1w3wv"]}, -{"isUsed":false,"words":"deputy paddle column smart peace connect silver dumb pudding avoid drum outer endless speed turn patch reason clock company charge prevent scorpion juice target","addresses":["WY52gUD9E4AgCiJatBa2HFe4c3rb32mQzy","WY9chZWddYFYZFuwUhFNeo5KDnY5K26gCr","Wmqjkr6sz2DQXuxeBGsBeCNjjqZkTcq2bg","WcaghU5xdRkjbnZHLWHgBM7RL9FeyQZyAk","Wc6Qmw64Q2R49LrWJHAS1gTfgT3E4Ck4Cm","WUVcnDY9ZcY946D4osqgGGAru2GAZtBbYD","WmTCcmrzB6TQ5HR7oyYVDV5TPPHkChoG6z","WfwHCKJReXz6rg5hBcSePFcuJEagGWg5Ae","WXxMBnTSr6Xt1NQ7f1ybGWxdfWuSV9h3Rw","WdyuJnHPNAL5vmnYvzjY49jqwm3ocF4K1h","Wj4LrZXB2pZ8qqdoLYmJjCys4q6skRnM75","WVgiPVp7EVrTphK35jGn7q3vZBYnXqBFSk","WS9zpUb8ayNa24VY3SUGdbCsBpyvgQ9jyA","WXTjXe9gGXAydM4pErTsSi19qM7RvTDWoK","WRAamVUuZP9783ra5DeUTzL4LxcR7Q95oh","WVHGf8Ure1sDfoKzTVH14a3gYpVZqfSQrt","WbqHKy4egGkynZ8uXkB3kYGiWE9QThbZth","WkacZQkawK2YBeRVz3w9nDUgMp1mTGLnY9","WVYph5xfRwDWh4Uyc2YBGikUL8pf5bzqZU","WjWWkWh6H6VHGuins447VC3GDf4Rz8tncp","WNkwGKkX3qsPTRzKHD8ATNsejMMJMpLQEr","WPy22grYt6FfzdDXxQ2BSQxShLajGfpRwb"]}, -{"isUsed":false,"words":"behind primary bounce armor accident cat vessel similar text carry polar omit orient skull rifle cotton garlic output puppy palm view two sausage high","addresses":["WZt3P73vLwa6eXJNa5UouGummuiqp9t9q3","WTfjGLnJ56NYmJhMy6mLJqj6Bci2tSJu4c","WQyjHhoYyqpFj7Tv3Ys8gYQP3aBijuE58H","Whx2NQkeCfiLQg8X4kbQ5dmC1QoW67B76c","WaqHXVuCpnZu8fTQRbM7Mvsx4YmMzpD5MG","WedLyDPkuKTeWSsnVsTdzYRdD6oRv7ZaJT","WYyaiXJ9tKFhzNumUDNJvQ6EGbSVHk4WoM","Wg96xiTYLvnD9oeXfRHri4vrsarzj3N5Fv","WjGuHzwniUTS7CurpdNYhjnXtn13ByBQHd","WPSQNnG8G8KhM9Ay9kffZnJkcdNMXDuAMP","WdywQNrAExdL2hyavfmgtx4nXyFvYu2jnV","WeGdogHHYHaHR1QC2Lb2Cz4QLKzy3ezwyc","WiCGhFbYKPsC1p3esXAX6m4idh8Pe1gcdp","WRRaDnhAk3wEVFTNdiRSgU3X9rWLPdWST8","Wh3xeaCkHGt2ZhduyjzxtZdw9FUQZ4dhFw","Wdv8UkfU9YRNvaGBE8EGUWwVec1xjMGBAR","Wmdw1RbM8BNfPxwggUJyRaGkjFpzxd7dHE","WSgBEPXxJ4CJzjpniKJqmBGhC6yqy2WR69","WggjHXLFQM6BftNEkQHJqhUaD96dzS5s2r","WPQRzNW5mBSFK3YyAoSSK8AyCNzDeZdeEr","WmUZhvMNhTK9P9q9bvwrGYbmhBZnqKroY9","WcrLqvppKjLJQF1Lndb8CNWxf9yGekVEEY"]}, -{"isUsed":false,"words":"brush casino alien camp feed suit shove soda topple elite hover air pink erosion desk vault trip sort garden lawsuit crime ginger tube broom","addresses":["WZtX4m2GYBob19Cnhz5qmFW8jxofjMaKT3","WVz8iBkNnah4hChJarDeqwq9kc8b8GskQN","WaLEvCfCFVqbyg6cvZYGLMj2rPgrmcP22z","WfHUbGQ64wj9hBmSA1L8Zz9cN1qibxt1Hr","We5PWM8ECn8HMxrdoy8d694vH4kpK8x9To","WhSYfeqtBfS3NE5K4ZWX4nB6EDYewpyHqq","WNkNDTUgeJWRiiCusvEXqrKEaCTzf7zCZT","WdXj6rhiHpzaNXtjNufvvcyJijpxYm8V6G","WfcrYWHomiiKxZfBnTaoZNapH3BvhTzve1","WY59SAdAE7H2NiajwwcPYmrDKoQCBAnBJw","WiTD63ywALQD8rMChgXcLEzFd3hWzREWS7","WjXeuNdwHuFDvtKffb6JnkzjPa4dujFaJg","WSb9cyoGDc5mhDmnPZFWuyfMvPTZiinnMD","WcKPdeAgi832zvEiVCHQJoVQRHuniShVeS","WmXoHCJrD2HxAeGm76z8Gz9KKEokU1YBk2","WTg4Q3bdq6D9iJSPp7o3VeraNN1vvuFAeS","WPNUQZQeASGfAce6KyZGXJ23AeLhs7swVW","WRpZCCtDVgo4fj8PdNhMUCCvQpkCtJoc4v","WNiSGbuXuUCqt9CoaHpcaV85tsveZJAFgG","WcKV9M6WTwAuzHzjvBowRkwAwrgEvWLxHt","Whi4SaQK3UuSPcEoAoxqEfW5JvWDcczyby","WiUhdabLPwzqFMR7skLWcJosFMiUAJhQam"]}, -{"isUsed":false,"words":"slide burst final armor rally benefit ginger crucial proud divide risk initial couple alpha drift legend canal sign merit birth marriage degree anchor artwork","addresses":["WYr2vUPx4RzNfcy3BsC89oKG5PrcuBncg1","Wf6cEFnCsUK9X6vnzizBGXR7jKMUcbE7gB","WUS1nyUHshmzXwxDY1QsjtYqbh48WUU3yv","WPJmQCLmC8hp5EHTRhx9o69qUFSAL1Mzse","Wmb9Sa6zyFryJ2WkTodmJ5rhcHTxFynBmz","WcwTjP5MbBFmJToVSC5pKQRc8ztQz7M727","WmYi15f6ausSZ8Pxuj6ZRU7UbovayUzwsc","WeD2dBpDAyyPpoQYHnxzV6uvZHcafgNGX6","WRADvjs65JLp9ZPUNkxyDXMmq966pZZBpo","Wh4MTqtdLUg5ND87ZrPevSSMREoWCRxRSX","WWTE9FgnjJLUdLxPTYuUj4QvfEkydaJuKj","Wf16fTy4gVXsbqY6etDhye8wz7Pa67U5rT","WSE3xtqxh2hJ2n3kXPfjLjRtD6cTyFftQe","Wjr7N9e14UaGYTAcM6VM4hmMfj6C8Du79A","WmqLE7X1vL1NaxSipWp1xV7YtKh99HwTib","WiwcDJCXFgQXe1gS6Ltha8C8i6j8CwPcGc","WY5G1XAZt1KRWFwGizzQ9Hh28ZwQkUMHqs","Wi5useVsPh4HLWcmuT1ViUtj5zcCM6BLxA","WfRRere2ns2tSXtyTsQWATbMqyeynYGadv","WNxQ5ZW1U3yZedXTkMusPkufrFHDn26bSs","WTuq45BnD4jhU13U9PyWfGVV8zeNV69UNq","WeTaNjc288wUMvWahVk5FRuFHCLe9PCmgp"]}, -{"isUsed":false,"words":"kid mammal hold imitate indicate toilet fiber nut vessel list aerobic rebel improve kingdom hybrid disagree funny giant deal chase target sudden open flash","addresses":["WTTKJ6k2skfSdufwbeiD95KJhxavDzbREv","WfFpanhfwrUv8gewyuNMKdQwV8qpRFX9Yf","WbypQ85KycuBUQhHveaPHJCTfQ6NeBb56a","WTeMVosvDoiAij8XoLCiJ74AuLNE8iU6Sr","WP9rj9yJg93FRSGwwkvYPTjW34VRE4jM4F","WicK1fTq2o4KtWRBYhD54xJRuScT1dQDDa","WR7Rc6SF9pVHa1dpM7DaSYGf1z75ESorAW","WYYjkZoeVNj3msbsoQp5m1CJnTi82qbg8U","Wf6sQYzJ1z2WgtL6yWMwF9BmH5JVYnrtMQ","WTgJ9eRJoH7H9LBrfKi3zHTskPJNEiqrWG","WZDv2BgzhnZqeMezZoQcKTjuQdZQ83n97P","WWSLvN1TDitfNJRVsysrxWCbkBLFLaTwFR","WPTJfzZ4dMG3bX2GTZDshfUKZ1JKxeAWNk","WaNtepuGganVfAoqA2s8jq83bgkeJ9Bmte","WbY8xZ8WQkJuB7FzKcz3S9SjxXDKSVYuqh","WQXrb4NKEmuWJw8VEd81rrgJYg7ebCUJk2","Wjd4wySBPGpvozekMDD5uA72eULd54yVpA","WNhb3jXy7tQLUoJin6rbGVpitD3zoXZQHT","WjRZTqGxgH8Zy6fCxw8JesRZExeERBhZcV","WTSV6WDdbPzYHJ7ZXCCK15hXSPXMjSDwLM","WakRypAU5PxbTHBXKL8t1Sg6agw1u8xwMB","WjWEtR8bsJCCTfCUxKejYeXtM5oaKCwJzM"]}, -{"isUsed":false,"words":"deputy peace merge chest fox wife drink measure chest gesture eager cherry solid pony gallery dash trumpet receive possible swarm original better face fox","addresses":["WmMvkMRBG4NGDsq7XNfrn2w6iSjGbcbjWy","WeTbZ4xHEqiNz7z4yAZMb6oK7Mtgr7n9S3","WbqLmbDjntrSDaSfmYngUS7Mu6nJAhFYqL","WUw4LosXEqQjCTscU3GZoC6P4gid1Z2jqe","WNveudRE7p1AaoNmRX6pBRxbGWSG6BEn7j","WVbPbj4YHRXLK2MLpFPGyAaDDEdZoAXf4u","Wh7pPFu2jGumASYpnbrwBcTxuP4vgNRmkD","WmkbpCkfX1nwx4ayyJbjYRajxgNYNjHtVS","WQEteDsFuaNSqy8gYeCJuXBJT2CMfhgYD9","WPWGJBLMXZDjbiC6TXeKEXXnhKMSUNwmP8","WcxJUZMZGjrhPGraPEhj3ptYW2pk421cBb","WZpwp1Hz85Jhxw4tEab4fpqfxi5HVGmQXJ","WQxhLT9qRj6ADrFagp5mu6e1Y931iUKF2S","WWCbSCPU2LAGxUEuDQ9KPG3h16s6vAsJtT","WVhfvsDPd9khF5wRotbSUEk1XQvSJfYQMQ","WX4zagfouQUdLKYAVPPSaPz6LKs52hJgca","WkHYmFP2bWhKYa3vnkWUwiNNSQS1QUVkWx","WQqTHAPWSuMpJBV6kpSF4Upxx8REmMKw35","WXf3BpkJkwwzm17P7gchBs1uVhizqw6ubC","WkguXvbRnyR3Wt51BBE2W3oWuwRUypjVxe","WV79CJvfphnhWxdDMSzrjj9dt6sdRGMZ64","WcA7rBs4We5XMwvR4WUQeGKihqKQuWJ2HZ"]}, -{"isUsed":false,"words":"margin lens giggle tragic one flip chimney shine all feed short tortoise ritual jar season mosquito render round spike match kid idle crowd satisfy","addresses":["WVXS4ALW725D8VRC1gkJDBGmkxtBAU4gc6","WQUrMGrMotuqomeLrXu2MdNFHn2GRhMcwG","WdLrm8vAR2bCwQRJhffEPphaeYHAzZnzLa","WhpGrVjGcKqqd5ybcbQ9pjXkRe1NAzc2g5","WaJipPPp75kdSHhi8qJHsm1495ZA2jakuX","WVJXC5TtTwNjLZcddTsv1SozULn7Vbivhv","WjrZEzuyZ5Wbiyjj36sUscrsUFnRJ53oDS","WkCoh1beqdN8z2xdqsduJCfFfe96xMJgMQ","WbtjxW8TbbWcGTn7envzXmPeK3eQVMiWNK","WP8CHYnsk4Tr9SemV68YPsUNKeMbXrxpS7","Wd3ZMdYC6ac6YtCCDeYoEeZwXqAoqZ6XvV","WPoV7BKgyPa6uUQS6D3BYKKtuaUFAzP6yK","WQRTwBd2krYXZAEopxqavdgqAvTmyTvfyG","WV2mqnDC6nxkuGmCeU8ax6JV43LES6tgqg","WPTY24woaPsAAEEnPQMD91guL5WjX4qeAZ","WVWuGZ2GD7ZfenmDvccQxCx1HP5Tab8Kyd","WVhB9xHm2KtV1sajuQuAmmdg9f4yPvFMmu","WSU16G6CJ9Y8fZ531132MxFVQCEYXow82p","WZKKSEqkNfaaub9b4zRUBnmAigY38xgPHb","WeQYmSW1Br59d2fRbWMos5BFu1VaYZ6nmq","WdpH2s9PTdg7k8NRJktCcZRBGcfcrYRE8b","WhLwDeNw2jrXmEvD7jXVNzQ579a2Xf8Fot"]}, -{"isUsed":false,"words":"dignity scout twenty base false slogan century wink defy produce hotel office drastic garage fan border regret length van visa unknown weasel busy away","addresses":["Wi1DGqzC2etXawNzLAatuvZPgAkWdEjKiD","WffhemwSVBGiXrq94ToGqtuX868Qk5aV2z","WfonAZeU9GjwucMZkhVjC8wmUqaqyCRfXC","WThSMwWS7m61D1euHoXv8AVaauf2KxiVMi","WZ9BswsWsV1FcGiLKDvQXKxqF3BtnUVUyn","Wj7JkmM4hTaSMpFXqPnNM1mDNxHB9xF3uh","WjLGVTuZCQGMpohkEJBzseCyryCohTCA5S","WaSgfbhHvuNajfpoFjU237iJU9r4LmQ7QQ","WinnanDVg3gcwSBH8L5oipq2FjaUrqzSyD","WhjUYFKoe55z8KK2dsgen6CYFf33yHjgPJ","WS9M9hn6wh6mmAbdy4U57LKhN5Vukfekpw","WYVDdyyv7jsZg4BS4VdL2hys5bYUsbS7Z4","WPn3agrgapEFFnq6dxJfCzxY6FFKxjyXUj","WmAMEa6aQpjiVjxQoDuJepyxjthjGMtbu3","WYxWdXcs9GU9s559TqN2jM7ZU9CEPpTMbd","WRQk4NGhA6PmjC7cgx2iQnnynJBSzrFWni","WiRYAZwJFamkYN73HnaLUVPMtvMrxf48af","WVrbygZ8J1fY9khrEtoTg5Q5LUDqdrosFe","WftJG7SpiajXACeDF57SALPF8F5G7zcWtg","WersEvr7es3p6rP8P5gXssSWtzkJNWyupT","WgNyZ3UWEW36tp4MHBdHeXCG6Q1fDhoSdW","WV82Jmh12rzgQHCLK3iuLppZDbkLDfRKVk"]}, -{"isUsed":false,"words":"adult surge avoid bleak rebuild use outer crazy south actor echo artefact ceiling dutch oven grow typical cluster grain vanish normal tank into mixed","addresses":["WRL9WYMNCcvo17pPoNK93rerQA3RoGcMxi","WUe75BUjgo9SM5sP49MdMZhnXu5a2mX143","WQpHHEm4q24SvS4yz1w28jHVmaHXxAQZLB","WY6rnRYBMVaYc4C57ZjuTf6rmJsHwsUopx","WZhPxVfbwS51GL5thUcJBxBH1rFcMcZbno","WTn4TrvYkxnXvFmAZgEjZMiJ6Rc8QsYMJ4","WgeDGF1x7k7sTaSU99dF2chDhgVLGSAnk8","WNrjWKdf6osAkgJNNUcpUGsyBTAJJ5ymuF","WX9bv53DQGUgLPxiW3d5gxbDnM8tg4pySz","WP7voxsJioft1bsnRctB4rYQci7KVxYECC","WkMUX3fsnU8YBfyPVw4kvHXfphMstGMGNG","WeFUCNujRCJTCFmgMPxHjKJJDW8eDtHP5G","WTpYQtPSMT6s9HUKFWYLAqF28k788pDnRR","Wc3hxSqdqwMK7mcmUnrz7oUw6YnZTNdcsE","WiW5cbrEHQBwnbsjMP53FgaxgzExYWVFz2","WSsSfGEYBQBFREySov6v6GUVjzP87gTVV6","WSizScJvyBbvdbSMFT6SX3nzt539duF6EH","WPYLG9bo335wqY1CYnv89k1h2Ufotf1NRy","WT9B7Dhe5y8j7rXSd4kE2jN1rVuF52wWfW","WUSLzfxCJUQgxMSunJKC3vXyRW1XYCsGRW","WVs8MGaFpDxqL5N9W5GLRv3DspgTJvWs9L","WYyxn4pRsJDoxZUbiNRsRfKe4wzaCLjv7W"]}, -{"isUsed":false,"words":"blue nature gasp meadow spray beyond shrimp roast wage service vital stock kiwi acid super choice coin blame clog orient soldier stock sugar under","addresses":["WQqKXZXx7QpWhwVP5nBei4Y6266V1pnV5W","WdnEgwZVd2yfv12td8juctxTPaYMvr41CG","WduiFzboQY2LFCTa8dRkT1DD4w6amHwsfG","WcsCkKbjWn6PoTVKcSPduzu3p66XRij9Bp","WQNp2U67hfQ33oVMj54x6JLvGcoMiCzEaf","WR6wXTq7T7MLog4bLAkJ5Hxfq8vnKAEwYM","WgBMyHNZrSz3hFTogByubkMWpij9kfrXGp","WcEock847wrQHNi7fNFdd3RorBfvAF5QHd","WYzo42kE5M2SFjBXJEuRyscrGWkwP7M78x","Wj8qhxvNS1GMr5m8XfNB98YshWT7SrJNse","WeUgXuH8nFHUoFv6eeRws5stG8iyjQSexf","WNnG1fmW9y41yZYJZshxw9qZSRpoGXGNLm","WTqH6SJLJK2mAm2tTRSkJLn5fYquCFkzJU","WT6PMyUMAhVXQ7kynRcEaseGqU7dL9Wbgw","WVDd3VoMuHuj8XFBZYZogsM7zPDU4fdfzM","WQLNZAESqoU8rthyUo4RBvVNbXmdhbpHqx","WNyjSXuk9gNYbxz5rhYb9zWnkHbjnQTwfC","WhBtfC33mUBfDf1UYaNHqU2dBNynQcC385","WWpnNRYys7DkHjXsCajvDKia1DTN2KLPVC","WTixQDMrwHMnQk9u1399YK8TMKcrHnCVTi","WehCrjjCoFWuTiF5Asp2ftdSznWZm2HKid","WWbWFgx9BNEHoq8AJHzSffUNgcD3ShSzik"]}, -{"isUsed":false,"words":"ahead adult view admit attract welcome trouble reveal luxury company position menu answer wire motion egg dose trash empty sort link practice unique weasel","addresses":["WiChL8mYhwDCpQqcLX2C79juJGnF4vqzpQ","WQx77Ts7FuMWCtx1EoNnhaPDAfNnpaWRFc","WdPYiXFZrFuLWqxKVbNCNKeio5uSrufRnR","Wec1J1ACSWKCAioop5xfQhEEPiuHL4DzhM","WbohBE2AWP3VkCXE3bDMjvDyDpSarpjnbS","WPskUC2LZQkHmeGY8qQveg4LfXeTc7EjL6","WWYYfEsdc9J27NZDT1Tp17idxZvCzKkevi","WVCFQYSseuE7rvXR9Jpqv4kyyNT8d6B8jn","WQCunTz7BjG9q42hSiRH7RtKGvNYthmEsc","WhvMqosWEA1shgrpteyDPdwqMf6f89gq5n","WS3UPf4hn2W4r38FYcgeaqWXW5e5wsRbD8","WUDPGoEdqWw74yV2phoJKxiAbTQyefsVTo","WPCTkNigPBvQ7rnCQHKCVsVSg5gA4Vi7Eh","WjJ7LzLWtYeboaBGq6qGYxQc5WRoLfhDMd","WQV1jcjKzQqKucmjmdGZkw1XMxyfL2qzRw","WhHo8tbqj64NSwtoqPiGcges4PSHa9kVia","Wk2M7xcLfbHuAF7pWhMDZrqsgHZvhpT3Zw","WmMxQP7XZ1VgNCRQWLkXPdkLJkA5gCRFHX","WjyMTxsLGwNbVkkEDcRvZG968QJL5t8WRs","WkgitwPcFYd16PP9nXLvfLW3D7ybu5U72q","WYNpaBXghcwzh9gev9G5QsVbxGmbbM3BQw","WQPQKW1iYKeAadZujbxSJzmh5hMb6SWrhv"]}, -{"isUsed":false,"words":"shoot cousin diesel marine latin street day novel wild garage pumpkin click earth result option run purpose case nuclear pulp involve guard friend jungle","addresses":["WeTYZ1jkVrA6iZUCQ5f8e9USevWxggRkcN","WahsfbEPCvxHnfyRJZ7xNZEJJ4PhbKKJCK","WSFFMqsNWqSdKqeSEFpx1t5zuHJEAQT8Go","WmNAWCRHiGfLsiAFwMik6oTdgsvvMWUTz5","WU7JpYepqYWxRHwmw6ww5gQCW5bAF9esgu","WdhjVcHo7G4K5BrJJG7C1p5hodkb4L8rMg","WPU4x3fZNvm6QY9LB6hCyPd1rCnVgiu4FT","WjPALLKyyZr3UJe7tqaUFtQ6icoziCBgpu","Wimm26pZUYiZ3RFhZ58XgNzSt5tiJNid3a","WX3eVNKZ35BAbxS8UuApsCSFrponwquhsu","WkXHzkQamjs4sjLohGLmdCEf63M5TbRbDY","WmNcXE7id6aPitnYiuGhXGtXyd2LTFnqpX","WiLjxJT2Eh38RuKf7XaaK6XR2MaXs5aLUg","Wiyn7fj2mtXpSENoQKmfTf8rP1y9qYiDyR","WSXEs8kkgWX2viWnwAuQnghnrt8UGrkiWD","Wg46YHQmkKLkxYwtQpvJKK3ytH9deF4nfW","WPEWrXvcUqcFF4dyCkpmMMvsqHLF59Sjw9","WYSUueFdvSP6VocQbFdYVwKj5WFcmzSakc","WWb3v5PNoEPZYKoScSJY4KKd8Ae5juQx2R","Wg3LBDK3p1mXwYcUySnmb6cKjP3kJw4FkK","Wj8cWrnW3Ggg9izbTV2ccwhzF6URAANq6w","WYWeTfwEiThANM9gdQhTVUEsW66kgSq7Hg"]}, -{"isUsed":false,"words":"host humor shock jazz tuition sun today zebra urban note door hammer spin erupt stage ugly sponsor seed nose easy image turn faith normal","addresses":["WNpQnwM7xPxotrzV8MR6DHGNtrRhJadR8C","WTLhBzfb1Cfkb3orSbJ4VXENR9k1AuZuF3","WjcCvieUdXFAhs8WRRRYR2EDeMgjZpRsHF","WbsUjRFKREq5q7Qshrds6JMhE8x6rYkM5y","WdED1RyNqMogAhHtE3jtm8Jva5adww3RNJ","WUDyYpksxjfJQkFWdQxQqRZDYH7pjZtw9E","WPvG4mh83LQtJLvNWQ9LwDeN5kSSmozXwJ","WYiCHCL8kXQgk75emDxEUeEaiAK6YcuFVP","WmjqxcAc9XQbcgNSBU48rCDbys9tSXmErX","WgG9PcUT8qz228yv5kVLbkYNR15G1FNZcF","WSToMNqRsT1HYvdead2arWmoPKiYfV35Sg","WcVCRTJjf9DfQYYsAHjUvTUoH7hfB5qc5j","WTExTopzuDzoNn2CFkjp7aRTtQjD8UZqcp","WVxh6jDjJ9dUKKsVUwDCSkX5aE3zi9rhbL","WkiYUva7yrQZeqE8p6cAYhvty4uZrxCKKB","WZeGYk39CZjqFq3BhgjsDeLnUEj1NjHsrJ","WX6BrVhM1vMibwqhS8nCwaTBzMPBwkf7NW","WbZMHs61gwGUZDecMBLXVEntzsg1V9CJuf","WW1Pvascew9RLJJn9rwbVQLDeBU7meKS87","WW1v6N9JtBLtr4U8TMbXqtzLLKtysniJhQ","Wf2XxXsNUXFPb6eGy4FckKYszg3N1Sh4fL","Wbq3HhH4pTyVFQSfGzMo39k7HS77kVQXsu"]}, -{"isUsed":false,"words":"obtain any twin sudden picnic energy initial anchor mix moment runway crouch punch road donor boost put broom fence slide enact maid never upon","addresses":["WcYp4JgUDpS1WLnqM1YFZBYkUKwCGxmm43","WQbqdNTUxGR5pnRvNTd74WWajdjj3QiFMN","WR2S121YGPwuFoScRDw2kJZSe8udtzp28K","WfxA659ridLintHLk4mh3okK572Znpo9Rq","Wcd6TvyBbCEJAtuFDT9Un9iSCpYBdo2rfd","WcDYV8gKKQToHJhA53LhchhbqcnwiY2thv","WRVmbjxZg14SC32FEmtUH6JEBJCPNSdt2d","WZD2CsoWbAjAgaQFWqtyuWGBaKsV1mFCEA","WPkRveVkEp5yBq5mZkxBBCK483eHtZHR4a","WchhTDGpu1r1H8SU16DwW6r9iDoGnYwaP7","WgvbeH1aJEAnNwkSEJHByUWXcAXV1tSuoQ","WZmuK5KBesyJHeD3sa47GWgzbeGuHZCBpb","WQAHHJET25Sx3WS8FmxRfz5YH5vCEo9trG","WQWqZvSuEBBuWxVXK5CbERDzBF3VaGC7q9","WUZSoRicZ8S5abP4KHxRhm5VcTfEkeSmEx","WWCgd2JxaBzTgy4j3BFdkv67Y5MWudVsAs","WQSMLEkBHayxVUQdoazTGQoAw1UiC1UGgv","WaSbFardPdihSbWQMnrLV4FZes8PvRPyBm","WZ6XeMuqP2jEjJPU6sv5yCWEdq3KUPPidY","WVAS1aQqiTt8fcZgW7Z9acLii1ziNSrbFW","WarwxHMg4Kjsi1ibURG5W5hiYskCmL6cF1","WkvEUMVAtLeoBW1Zy9LJf4p7yEjgrAJmkf"]}, -{"isUsed":false,"words":"caution unique salon plate relief excite bone reunion lawn code else april topic emerge walnut group cloud pride normal lawn shiver remember scale unique","addresses":["WVZPLvqCB9YcYqtLxY9dwd2kKvuQaLkpxn","WPSADaKijYPy2pAS73TYREQeFHzxmXNSQw","WbtVta25sGRotEzGgf5WhgxtK9y2KSwUr7","WQuJeywUqb9kkKAp96BrkW2a3N9S25t6Pk","Wb2Bum8p68DTfeEjd25nXA3bHZ6MkzAEVt","Wh5zctL8AgM71bCwVgVEMDHDEa2bH5fQjR","WfJo1VJ4qxZuSisazk24voWaVNremPLLYw","WZshU7WmPc71CZam3MM95Qe6B9LrXD7vAi","WWtQVxqkPFmbiVKPpxR4CnT8JosjQyh38D","WQD1bbsJDjExCcyW4bJrRK4CD1mLTkjTRw","WcMqC3BRNUHBTRsj6J4LP8qbsYXSbPhjwz","WbPtyPqsQUfnjioq44yrRpWBbPJ3Kk7tjp","WUmhhtfkoKgxbC4JyNCvHCm9fR6HKBugE1","WTqyRb6fnP8CrrWKTAd3wmwKaCZE6xSCys","Wfy4yj4U5UET6ceMdPWG7hvT2g6evt61AX","WZQgSisw3rPhdjBEqFrugQTV4iSeTSqHmL","WTtTMp1bL72cjULsfD4k8yYz4Sk4So4SDX","WPxTgB77vEu7smKBuckMmzhaKdKwe4tvmM","Wje9FKxFsABWJrPLKJKxHYh5SkecHTszCR","WZr9uPcZRQ1nTsD99Cah9bMgK3b9mhLHSv","WXB9dRWwvshJGEcBp9NJAAZ2xaJxmMjWqc","Wgb76f6jaxRXdgiU3QkVnvA7sABxfjmnF7"]}, -{"isUsed":false,"words":"reform ecology delay tent inner olive logic useless subway harbor bright sweet latin stand arrange link combine gain panic denial flight author feature fortune","addresses":["WRjDASAoApAuKgQ6RuHwHdGNQppt7hcFK5","WbxWAYSudh5rKPxrP6nttMy1L5xZ6qy6Qk","WecmqLMrkBb8Ra7fTV48Ey519xP8yQAcPi","Wip1eVxC4NHu7zJ2YY4anDNLXCb5XT2HwW","Wi7hA9iQWNMsnvMZmjJWYSF5HbjGyqRs9o","WhyVBU9LtLCgKNwmXoKomoenRJPLseRTj3","WT84WKxNcWRZJRynzhRugmeqS3r8HMVY4f","WmNq1UaKCLbNJznrqJBHxjLpTpkjAu7Jo8","WbbUcGG9SvbHmp2LW1AVfW5S5vDrqCmQqD","WQERfhSZvpeR6Gf27a2hfhKXLyBjACE6zN","WhrQJ6uyzqp2dTegHBuYB1ewn8eGwh3Ain","WXCBQrB6sQ1JvbGhayghemNdhoSUaRZUBS","WmJnXcSqGKxxxNKaV2dhzVBoJ575uWQCJM","WYVNu2euYJAnykrzEK4tozWET8Nqc6wJZp","WVKZS73wq2YPvxakMEh1a2KWBvueDjHrzj","Wd6ynZrg7gfSj9rtFdLnLAGdHSb9U6bD8C","WknWqVHmumBg7RHnXdCLotGct5Tf1A41e4","WXPy9pMHECK32ABWCS2S3NRmXAVAkLKYLJ","WTMsYVxmncsWKY1KFKJS1DgBoXii6xDwRN","WbBX2BT2BjhgH9CfMZ9wAQXUxHQG3jfKy8","WiKZjLdQ7wFNj4Pf1rC3jNBL99jT6wsp6P","Wg8TEfPVy7FzPiKxjxqgMzaRPpVNkGqc4J"]}, -{"isUsed":false,"words":"mammal fortune legal tackle stairs disagree silly around salad bleak sausage bonus treat april unknown trust border supply common purity smart sister foot home","addresses":["WiBQcAhYecvMQNiScN7Y8fFc7zSqou6Poe","WemHXtDdFp25NbnPPUV9Dro9qY8ANDu1aZ","WjaMoYp1BUv714GSAnaVuZbn4a3Bn3pcgH","WQKWQ3g37CSs1ujyuz7abprsWzr7FbHHsi","Wg9Z1Wb3c7WvzZzVGdvy7kdQp44jRN1ZQ4","WPgFchvv8n8Tvkk4jcLufnszuZ3g5nxJbt","WRUVYatqaxLHMm9A163LiPpSMefSTrQAfJ","WbifAESTAQmuXXGxqwcixYTW5Beo46KKNU","Wf6BkjWsuttDKzdWJ8W6wATTDPTU9WbJym","WX6qysGszyrkzifXUY8niZKRG55XfXfn9F","Wc9mfYeQNRkjqNKL3BxEmTmFQ1TWNQuZr9","Wkvr8Lvm6UsfK2hu1dbR7k8j1XH1eux1q8","WTFSGpQNUcedJy4rrG4F39g34Ad2RR4HLH","WkckbeLPMyXfRvedcDymR5o9KvRrwXMzFo","WejXgikhWrgQJAFggw76Tpgpwf49uCQ3HL","WPDKKjjY7cGXrbzYuDS6GGEC4VrjkpVjnZ","WhXLmVApkLDaGwDqqrt9NpJAEM8PKjPQtt","WQ3XhtXJz3gg2tcUs23DHR54DYZUr2mCN7","WW4jXSxpwXvAZzqbknyxsoQbgV8bvxsKNN","WmVji6Sstd2VTf7fmhAV2QmVuVvYh4E48d","Wgfezi3kJYrj4Y9DLEbqFSnqEBzVdUt35p","WVqjryWhoYS6G1y4R6mXzxK3tY2Y3HazWq"]}, -{"isUsed":false,"words":"float industry deer renew digital bulk vital design trap sea boil morning easily armed slide they rubber sting name slide fortune nerve hamster truly","addresses":["WfzWaDG6TAPMnxMoAoPK1h5q8gMexBsQj2","WeqA5ajBbCdYXMXLDQgJdBxPQQCrKSnZMc","WiLmxVDWrq9ZjAhJCTQcQs5PbkWcJLx9qy","We2T4jihsCcmA4ghRsXny4jYKcsBHDV4J1","WPBSd6dnT1A9689zxzHT7cPqoVMq8tCsci","WYCTmjX6NTFPM7XSSqKk5jHHrHtCx4FB2Y","WTPm7yHjdsXAS1iRRP7TbD6dLZfWuwUa42","Wc4uSfKrwJX2FUWPiPJybE8mm7xYN8JBca","WeiKJfaGkDkicY1Fx1R11E4CJfdffzbBpf","WhDp6oqQw2iYrtP7xzc3e8eFgKsQHzZNDS","WkvLFPdgpDrDY2NWdSnxcBnSZQEPC4ZKk4","WjLw4EUQR1peEqhPr6ja6Y98TsnsY266bt","Wg9P3XWqh1Gko1wK4Eytu1qwz5JF9vMhwe","Wd1S69WrihFakzRYu9XFimNVgBd5d364Jp","WjWvDTYZpyFJPvUEWQNdTvWn61fDemkHU5","WcMaYYx92QRRgrcwPRdzFLA38qDsMwuapS","WRESFUrRFt65ucifLtpXw9g2jmkhSJ5pdu","WTuGPwJzMdnzbvEpxopgwSVu2RVsHsK1mB","WQdy7PiLtbfPPKyB5qyQdT4c4CA8GCnuMd","WkjrBXcCYi3Yps4YihcPPSQPaZHtkGkpJm","WgpSu9irhst4iWZqbJpbLEqP5iGPJeadLL","WTND6asUS4LsVnDn6778RjrXpxi3c3TZ7m"]}, -{"isUsed":false,"words":"sea view twelve observe ability shallow lawn atom reduce tribe seven turkey expire sunset glue spoon film seed practice vacuum main gossip jeans lawn","addresses":["WRJEP9RtwgEZtZ5e4G5zLnTe8vQLUgWCez","WT7YJeRdXhXViymFcDVFK7XHStcFqy937J","WRP9PTwvHD1SskEEZMnx4ZvaFdSHk1Bdqp","Wiy7LkkssHbrouCwm2o1e8zV71jqys7pLZ","We2V9mmmYgzVmt4RDKBQqEwEEjrPcJbCQz","WjbhGi7DHicLaSdT6y8bZ3TgiTqQW4wLSa","Wcgw4nwykCb9ExwWPyxnvSDy5dStoHPUWb","WeBsLgBhH7SAJPEJ5eh2fp2QRkRKpPf9Ax","WVPs1sqJPTYmV59TMvrsVGKQ5amVG3f4hf","Wa5KyN8ZDoFES4DnX4p8nfxntFCJV6iYn8","WYAES6caFoarAFp1dZUNXuyjnjZTbir429","WW9dWvRWgBdkFTavPhRhrVAzxW2qGjAkCp","WYuAVN9pAXcC4tPkdsFa7UGqyYXzuvfkd3","WbCeDncjndPoQmsZvVeeamx9EMhDn9ExpX","WRSi4pxzs3xjHr2wMXFCenGCSX7a6XxxYx","Wee95VYHXo6C9nzin4SrW1S54ARH21GwDe","Wj8pvgFDVfKKUNVrY94FXHKx1pwTCnuj1R","WTVby1ZfTGRmxpZmPEi7jVoFkLAdy9vFXW","WbZh92WPMhshcbHbxR6mGyCUDArDNm4wsY","WdYGJzKixvG6WDGWEnMDLsJUQ4UDDiQPuS","WPrpceWdYYm9gUdvxF4Xjo7cyYR9z5H7Lf","WQ76UM69Aq12N4QAwAuvxXPKnya4r1TzkK"]}, -{"isUsed":false,"words":"violin elevator can position alcohol feature nominee grass move find together blade mass intact certain sure umbrella chair teach ready double assist wolf reopen","addresses":["WYe3uUad7ZKTYdGtRujAyXdiRNZnp1hZMv","Wa9rVzBqubPboUH92dsSXJ2rCPTv6vyiJX","WjrRLorod4qnA1EVQw86rHvJY837Zxe8xa","WbkVsJQYhkMjvjSTmRzcb9J7EHhMAhNXv6","WmLrdXPwVNaitFPkUSC9WwCtQb4FXevDph","WhPZ8sfDgYhgBaeqehwqAxDnHLA2e2FCGm","Wfwp8ALYN5MCC6ME5NAYZRCtXHG82LnR6L","WhWzMsPYP7SqgeBCRnn5ckwLDAgnrwReop","WdA6gCJycR94c3f1W3P9wKVWXCabz4Y7rN","WV9nKXBKmnLR8rQrWNGYpJbFmrDZPf3tgk","WdtSGQ1kcwAeH9Ak8EnTwufYxKvwq7aMAV","WY3K6H6oGxGgSPKhFnU12Cqb5uwmRL3vhJ","WQRWWv3wyQohkmLHABZvw6RqwjLGnJduog","Wm37v3sdMxEjcMVC2dRUGx5mKo5imdvaw9","WasDpeKrq7Umr54ehtW6gMKDQ78pSeGPkS","Wbhi5E7bRqEWnd9QZDE9rpQDorwMMxDqCs","WXuRQY1snubkycEdkrqLkq8XduJtHxyZna","WfVWy5zFmKVSTnzr8qVUmTF3eS2sAWTC8u","WVUB3yfnWxbRHra7KXvCLiG8bRnfnQbJMp","Wb74EPgQkrYQH9K5JZkNScfqb5RBvQy8Lp","WYXtSkPWtdzEyTavnr5WWnPZXyprnsUeTf","WRYMF7wn3McMTuEVAhikECtXHveuHkwJZ1"]}, -{"isUsed":false,"words":"predict account pass scout choose art switch circle ancient deal nominee measure filter leaf ivory category female race lock shift normal unhappy spirit wool","addresses":["WWTRsZ4HbttrS7FgfzTKVw3V7p3fhkg46Z","WPy6LjTTwHfsk7NuADmAgiKMSpwuKPzmjN","WP2YRzccEW2W39HgWwvaMbc7BeWkQ7BKts","WP6YwWEQSsByqCUgauhmBZgPVFMmr3DgLg","WhG4NURDcc8SKdevPGQZcT2Z56T4BevP1r","Wf2VezDUgRZuz4enGCf5kjJnRjmKRh5Xcd","WVteQxpjZu8o3U7JhEUKNdpfJLxt8qKAQR","WgtyVVEmxkQstiQQLgKENetKVTfADAk8Zf","WXadDz1r4UvdB42FHS8oLiNDkeDajVJ4mf","WhsZGtswDwdur6mtwShchqsSUUhmz5LpkD","WYgVvTyovyFwhZFkq1BjNyyUi8XEhpfrXe","WUpq8zwowvzN9KbGEVThrpycyaDyJWdZkW","WXnDjyQnSRdiwqbykL3hqUffEb97pMssVV","WSjV9tUfTP6NYH5jQshyMCNKNmHd9S5dxp","WaTx8xTLgLfBs6DkZ4ZKDweWYaZVWrYJ6j","WXAFHt7WEbnhbjE3PAWcNeg9tKQDJsQmQt","WaUzvrxNBS5WWXNJ4FcbZkNJ4WC5xWymRL","WaQvm4ibA8SoTXGUChQhVV3Vy7Ka4SWn1x","Wg8je5avpPriczq7jvGLKUhb6DPE4K6as4","WmsDT6qAXqoQ9mpsrfZ7zUTmumdHEJafAS","WkjTBezcbt4TQEeReaoYtK6hQpGcdeTrAJ","WZKRsV55A5Yf1wsCmBfs6CxLkHo6DXLXS5"]}, -{"isUsed":false,"words":"sort spend muscle scissors pave banana glad eye educate edit next fan receive garden luggage audit town butter regret harbor unable else penalty clip","addresses":["WPo3KocN9XHS1yGkTggUEFLyZmbgrtEdi4","WWcj4LwuJY1ocJA3XPEsoRzhR76Uh54Vz6","WTHg9QBo7bz5omkt6hGKznJqTofB3wuYir","WPS62fy9Vot7HSano1SAsAJDELHHK2Hg6i","WXVtnLBXaMtzGdQVE2vma4REKgMM4P6cCN","WejGPHu5ZPoLWqyt9wS7wuVZfiuLyRXaEe","WUNRSP8wjKqkdh9zV4zvdaRGN63h7aDdCA","WhhBupMBHEqjKsp9ZE9iFPjxSHFbuBdM82","WRut39Umq5PaMhN6vF1GC5fK3p2c6Su44s","WUEYEGLKjRgcQUXXD4Yr9s7BCDpQwC9QVv","Wm68wcyzwbkVgeFVTnSuSvF3pDxiMAe3y2","WguAVvCYdG5poe9ihHiMnCyCZ8PftP1HDk","Wd51XHGVRbvL7GuE6fwz86Ji38oQ9xmk61","WRxK8poWYKiuKGVZQ7e67jKxofWohWcLQR","WduW9jkq7GcxgRJgeRoifXvWB4HjBvzArZ","WXFmKzqYDEoD1GATbK914znVVNMhbd35gt","WdDLAaqgsjHPw4tDLgNPZXKDzp2JWMgQQH","WQGU6N8H9xCJPhDX6pWSh97b2uPWZNP9An","Wj8AnVgxS4KT9CwjcALJMvGuffy1FPXZu3","WeiSSPaftUuNRHsqJ9oTcpge3RCNzLDLfW","WciuHfW2gSAMKV2B9y1Dd7knNEUUEdRDVJ","WZT7BUZYjoCzNL3sxXTcfBeZZu8sxQTyuL"]}, -{"isUsed":false,"words":"just nut curtain slide silk nothing spoil reflect nasty ramp digital lion equip liar account clutch front gold basket apple battle exhibit tuna medal","addresses":["WXiyJmw2HRXzfSrLgNrY38FKjLdPsKDghH","WjD6E1HKyWiLyZ9Rxszg23DnKpCSw9rbJn","WWhSSAC7HpNJP8krkp6SPtWALGKYhUKaS7","WmJLDeAK6dTgdR7P566uWQggrTmT3wAzxH","WZYaxBmntiRPZXyEu9vAEBq4Maa4HGZDPZ","WR2syYCL7TjB3kAmsWcp9iPYh3EMTCmDqC","WggyVwi4EbPyzBsi2qjYoxxt11kZLsYqu9","WfRpfLT4cKybCsFXoKWWea4pYw28fXknue","WZrq4D8u5xDwREjcMZGULrdRu4AEUqMfdv","WTPr9RcwSXgY9EQWD2DhsY6wYDqP65qcmD","WRa1vGS6dvygWT5VLThgW1F2S4jhvTXVxH","WaDcLRVAAWuayHTNeUq7cMcAKP1aHnXoQT","WezaRUxoKiMNNyDYS5jVQxsxqyMRVCv9my","WZKZLSnxjZfLL5xosUTNTHazwYb9xvxJyE","Wmd6gHx8wTUzpzFnpsVDkgKQVkKspVJijZ","WcZJB91nBUmvFLUkD7wDhcTurpyLuTvnUp","WkhujjCrKLRS7WJy9YHS7Avd3rPL5Cuh7j","WauHcVb1b2yBkqYTVpQz5aBKRuC9pV5qM3","WWVB9PVxvQJzq2cNH3TSL9YWNEwdeUwicj","WgkK5Bwb5rHJjhhLEPfMeDTkD7QCQVgLTV","WQcMuotrN8GqfEobJQHwhUuLECLx9CVUmg","WjFGUmhu1y6yb5s4kRu8jGVGHzttpb3ujV"]}, -{"isUsed":false,"words":"front tumble pattern access glow merit ramp extend design material indicate fame owner ocean off basic survey capital rescue suspect genuine donate grunt spread","addresses":["WcUGj8N3MPY3682W3T9xpzHos24xw45YJ3","Wa6Q534bxgdT4BdHb1xJhNPdBABzcTmGG4","WVcLQL8NEnTgBHcrSxBnmNqUqhKdgzWdGi","WhE2Xo1dQAAhMSg2qZtiNUYxue74yk851u","Wj8P3U6sMNEzzL4npqsxDet9ZqdwxNVgUm","WfxpncZ5zW93HANoZhLJy6S6vmmUx6qawn","WkfuzeM2r3gyugB7eKqD6fTmeUVGP2Fj2z","WS8zfZkQebQ13i1qrhLQhDcbdi175RJoBJ","WZrskeCr2f5K8HrgYY6YpPkbhSDdNSdBGn","WYmu5yzkwPv6RKHoD1HG2Lp6smLwjPcHsP","WaHRgxHU3fvsiA98pyU6EwGMRfGB6JrZ9Q","Wdm7rTjyWYfQ7mEZzsxtKKuhQwYsiU4LAK","WYv9DRzxm7pUZ3uFPDMn4u2d2AGkb43o3K","WmFZkUrgPmnN95ZjGRXhGkdaC5GkTZaXK6","WTDepjtAikF774RbG3Sktaq63LGcKP5G4K","WR4H5Dw1GiVfXDZAHUtagwacxLAZMLbL9E","WcyH7rbZbA9CM4Q2DjkBEoUUL21ZAekq7i","WdSjiQhKx1qjSoKWVRKWBumxt3XC2cvyKf","Wa7kJU5g73TiGz3z9d4UiFeW1qzDJ3kuDZ","Wa6CWvQ573xFvZ9KAyXqwz4KLpdXPB9bSp","WecDsTqVgNgSQnvTdWQrHZ5b48VmrgKMNS","WT3UEp3dnZQAbgpGU3S4hTKEmp1P2kDQdh"]}, -{"isUsed":false,"words":"glare sketch fluid frozen jazz poet nut hospital concert close evil wedding teach idea input swift crouch valid find knife wolf forest cage speak","addresses":["WQW4uhYVxhkY5vJiUFD4icRckZTtEggNgf","WfMa1rHsqfR8jw8Vee2LPUfbWYZ4LTaMTm","Wk8F462n3ckv6HwRebL9SuaDTKfjZWnkue","Wg5wtkavh6wBFvLrqYFtCHKN6CwL2pjuJX","WSZK6dfgkwnHGdnhR812ei4TtCoXMaNdg7","WjjWT7KH4dFujzpwL6JZeVTq4RFb27Nucn","Wfm42uxE69j8uDyQPuHbc2uRtg7H7WXQRE","Wg8xwGN4BVF4muB6s95XCijDXedkbLPX3p","WNjbkvwnKvyDatL156BE4vrWh45om3nY8i","WQSN3QynYiCkBFfNJviLhA8oSSC7gm4X99","WPv9gXwNMdxjMFrL29qznkbfNWyvQRpn7R","WS6MuPbfPmwoFAV43Edg8kxwbx2A4Z2u33","WmoQ841beeqt2BZXq7EHBHdh4XL5uhYtp4","WmtcqjizizLrYfGDKNgMSN8doasVmHn9c5","WUdTWqyAEywu1AcdJH2faLtBtz1xAbxWhL","WTeUpXfh9xaxDXDyYALi3tYTEUMDRU7JJh","WUnCnmWABp1x9bSfSe7s1sfUiMWRKv7ufY","WmJvLeoXYwn9nQGsefcryBhV4RcuTW6mdv","WUfbZKmVjGnbM3De6MghUzSJ9Q5Liop6va","WZ5GFdfM1KnpX1p5pgH2euPvZhZeCm7iB1","WhskKMDdh8iStHZw3mNcRx3mdUbPcGcNdb","WVpq16o8ZFztHDFb6uSJVbzSyhA5KJ64sS"]}, -{"isUsed":false,"words":"indoor typical crawl other error wine cycle illness lyrics medal tattoo same gorilla early approve forward shock album winner enroll chat young call hold","addresses":["WZwFN2WaZeBkpP4bSp5ZousSaRA68YAbJe","WQ9MReqqrPfxyE9AEX8qVPKgWDkTPCnxop","WaGeG7hFNu593nwkQ1XVdikk4rm1thBUTk","WaKXuNzmZ8GxozauD2jdTLkQMfDKmeBM9E","WZySKX6fxjZrnCA6CZQoWeG6EDMLFJ42Ap","We5ePYsh3nUgeAV3fy7JCdupWosdRFYfia","WdWZjuXmfm2aS3YazqN1MqASAhwC44TmJm","WW2voxqQv3BG8U3ZNwScNw4u5KEyXGoX1M","WeSTfkmih88Ju1McyST8vMZKtBvXXtJVs4","WRVL7chxhgUCNkhEBxXmLRENA58j6itDSe","WkiCKxHttDnYfdab2JfZmvYWKM5sh5bKBC","WfrpRyYjv1bMGcHeE2bCtHZbYenkpWUYJ7","WZCtLamnWpyM7V9CoiPjEQ3gAirMSofvFg","Wa4vrkKLVy4SNr4Z7PafybYKV1WL2bCpS2","WawiRx5sBHAdSWhZaqSNvKa3xHNggFnyTm","WjaHwcgTTqUbxBqeuTCDfm3wykvCBWqGb6","WmW2oxNvv89nKpQEUf6MjxiAXN4V6LEzmc","WUoYbLyJyz11dwWXEcqQCctLHGBsLLZzWM","Wfis2pwSDqkH7r9uEgAuAhYXSRNhJhnp98","WQ2vYmz6UT5KubrMjB2hofsj5W28BM9RFA","WaMbRJGLCMFCdDSCz3TaWGQiFcajDd5dgD","WXeBHbUXb3D7ZZjjA31XM7BVRoUJJySpRA"]}, -{"isUsed":false,"words":"file huge slender double seminar shoe school enter cheap ocean author swamp calm wish kitchen toy address already slice view pistol intact basic loyal","addresses":["WdbXhGDKFnC4P2A9biv6MuNMMqecxK7vKL","Wa7YrUQ9FYP8aK754CqWP85kg1qDLqQkcf","WcB9LoEUQqKPdxn5545NLTm1aLVdPvBNQ9","WcT4tNSCgw9WGjdtctKwJH6XQE6J7uhoZo","WdT2L8LKh2qBpxXVjYT7pL1Xp1GChDhKWr","WXm5ckCWFyDsfa7L7RnBB1xZF8V2xGNSWD","WfC75Vsj5RSkKVX3yaz4cYixUPiufU9RcR","WTqkwKdHR5zNtpmpsiXEvXXtjPaLXVT7ss","WgFJdLQLBQ3qmdZUtsJj7SdTFtYuvgyfYQ","Wgb9X27aX8pcU1kJPvY3f7oJ3RZXj1K7af","WU9eW2jSEjECHycs6Drs4FNUuUhsDxUGQ2","WZozN8NfY4P8cnZRRN4YMe8oQX6weyK6Sy","WZV6FsjNKNto1nMSQmLuyw4e4gyJU6bhAW","WSBojnTCvURK72k4B4edvszhdpNmQwyPZp","WXCFvRQZMmzWrv629ddKnj6Z7rj5smGcLN","WUMuqZQ45GCSZaDkXLmq2epqziQCVgGZUT","WRNMcyuVyKp86VdA3JfEqcKSdKgLZZtbpy","WXJvjdLTUX6XVjV3GbKWWFTDdDmX97YnWo","WTvxeB9z77mswKdwi9oKKT4qoB2fL7MeNf","WazWDWcQk7HfDnQ2eYevrJ5eFbkBmPavUd","WW6ytmvKDwcgL9Y1RProcweiEoXhsAkjUm","WV5j2A2KU4ZcXXMzrWV4i1BPBwWYYJbaRk"]}, -{"isUsed":false,"words":"worth reopen race kick object mechanic need pill apart market chief walnut century razor october glass limb grit ranch together aware coach sea alcohol","addresses":["WUaqNo7JPNr7rosxRzQT6bFH6V5xCHUqbd","WUPSZ2NCnXqB5DbjXQAm8ZrXrDxnGeBDAc","WWJp3ynjPCS3WFchKLwtkYZ5X8wZUz972s","WWnugNfnATecWDvg8rJFBoapXFET7K1xfL","WgrGRC1EvKYGgygh1sVExa8kjMpTgCT1p5","WebnTyPXAEpwurEM4PZdAygrQwyGtTrope","WTMnmQXiMyscdoM9U7DaAsfPsgzamUiLAo","WbMtge83Q37LrTCxqjxMRKJ442Vo3UajWg","WcALpvZ2TucHKRooixstthizseLFMjKTq9","WYdrvpvgnYZs53o9zedykpsQpp2TtmveHF","WcW5HfpLo1sQNsmAyf2ZuBcSvrbXBtyPzR","Wjio1GujyR1CD8KAUHrJTCt4T4DnRguxDf","WSbZ5tPaUGXjvbUz58hLchm56UAx8TbfYw","WQKMMmjaVKKw44fmqdSesgLEG2SvYxoa8N","Wbm9g3B1FtNskfPC89roamqSVCEuieRQxn","WUzbThQtDRTH3gU8JyK57LgZREN3bbHpms","WWfZwuotq12shCFwkkq3Kq3Ha9uvcNAK73","WefQcjfLjma97RWi7pusx2YWgju3tPNSjQ","WThpAKg6mFVLfwm7oitBYfa8atUWV96PZ4","WUaKNzcwo9ZiroYjZMsfirkDsBGoEYvYJ4","WgxcwKQSqZ1auKbm12o8moYQyc6kNs9c7F","WUfJ64R2JZWKSn7YGBDDgbBXqjoTxzjfkL"]}, -{"isUsed":false,"words":"van gesture forget problem remember speak venture vivid tell aunt damage earn matrix furnace twin return cause estate system bicycle rebel giggle heavy taxi","addresses":["We5HPJq7yrawziyT4jAb8TP5EEqZDNcrv2","WcG1uoAL5VrfVdvQ3oTBB7UVBTY8U8KgDQ","Wgo3poxXC8mUmftNcg7AhUBiLBXcBLiLab","WRQ6bchmeacZviA4WtiAuXpZNj3wnQ8b1V","WfTVs1NHnyzbAwGZSndvC4EfoChKqZESnv","WYLFo4MyEEiuZenrsduYdZn95KsU3nAcTi","WPfdpwMipsow7MP6DGdHmNR6qPiv9NKXLT","WWQgVKAY1hFfpay7azW4c6aq2csALRJhPj","We5WZmQCJtJRzxhw2oF3Lk4YdQgvAhuCDx","WgTEyw76yypE8s3tK4nbs1JvGBWhhyVy9i","WYuyiL8BBonGN7ug7tE7bSBqfXFRwmtKHp","Wd58nDKQZa9Z6kU6E3y4X882r65kHGoh3d","WbWPU8DmMfPs1oNaEahptfPnA6GFq9eGUd","WR1kewdNCioC3yqep14dmWpYLFUtPnA7pC","WUPp7TJ4oThTLspn4m1gM7L5ejzYtjDao5","WSSxDP7xkbM9cTjHMrkyvcaMTt1wJt4xkN","WNhGytZhLX5NZeJVy6TQC49o63PEqsoMBQ","WjTuB4U6qSwzd2m8DZiQGxTcas58E8bcCR","WTvu7tEyLUQH7J4r9bAWs3jJFWnHmggmFW","WiecFXC8Bv3vQP3vpuGqe1DxLrTSVxawwC","Wdco9kgm4h6MG6L6MCwvHy43iToYytSDLp","Wj2ENs6T2BmNyJ5NXqMNDzxRs1Kwfjz9bT"]}, -{"isUsed":false,"words":"squeeze race effort parade asthma drive pulp tower fashion tuition rib grain parrot chair pipe rural stand outdoor sing quarter tank hand ability kiss","addresses":["WjZD5qr5d4N7wpzEC7y2dkCjRa1BC2rohd","WXp68EsGiDtrcUADfeZfKV7GrrB2yyvswj","WPWNh86wERQXQ2GXsftpL2heFHaXzGCqXA","Wk7hAPPUWtwS6ve2NJLadtV6SiwpB96r2k","WbMdLrNifYw2u2RMroi7SL5LhCdUPXdXGD","WYMBjY6Ghzt4ESPrayN38CMqcqGgGbLZ1s","WaTREyJZCkkytENSqCLEgF77f9ueYc1YEN","WhYHRPJEnUqvC927WJo16yA1QfNrbyaGow","Wb587jA9iQUsB4NxbKqCGmjr7FqcbVJBtz","WXBzvdjCrEPJYuM6ZSS431umpQyT3kkKaC","WhqVHRBwTuN8rHfJEAFZgG5G7HRCfiRoqE","WWAN7wjPjvD7niJVGu6TgQ4n8wMWAz2RuL","WNzhzsU1GqFwJjTWa5WcVoMiXiQN8yi4VK","WaEr3kYuM7qrUQcyiuM3yZJcuesbv2NQLv","WPYi4imCKtaPHxVEWf8qmFpa7DxxKzmE5q","WacUfBgUVrEYvbbpNhpoVyfL7Uv36JmYkx","WeY4jq5zL2Zx3DWB8vMnZbEufmoxF1m1s9","WmvYfS4YpPFgisBCGPYjVu1Vz8K3oSXYcy","WXEX7ZZ7EsLjgTDzWLiKaU8wZzVZn1WBqu","WU9M5kwfPTokzAk8AhbqE5AMSBhoNMx1vY","WiFiLRaBRMgP37Cqi14MsezJiayu6Qqowt","WTyJ67v9BJs71rfPQ4gvwiMeMMdNZZUTRz"]}, -{"isUsed":false,"words":"negative one benefit fan material story pudding stomach huge nest victory seat until entire asset rally ghost wealth predict top cup offer enlist mean","addresses":["WaC36LgXUgpX6j3ADadru2npztKi5NUqtt","WQ5tmDbR9rZvmj1sKmxVUEr1UWcLGWQxcd","WZjJuLEudMgdJWc2bi1zhHf2wx2CH1dJM3","WkwK72MoK4vymSrT7iYJn1xdVAcAYBsfDf","Wf3wumfWbcsasPnX1XjoEK4ozbTFWJkjSV","Wik8GpTRCNXmcEAfvmqZEZfoN8vhgMNHRv","WY5rbKrUUDxdNFjwvAeexaK9RdxPbQMeLL","WW2j2WfmHx1RNWQZfbKFSoFu9NepcVxP7a","WY9j7Db2swmHWaG8yHxvARYMwVPkvvqXpS","WdQzzsMoRNPcCodTRo6jqpQouxwuhkN5z4","We7htRBTy1aKPTGuEmvo1HVRver96v5V2i","WaXyaT2YvBVJR4K7LEyp4evPZTGjRCRvd5","WbKo8SyM7ZeEtvRFN6wJVinfcJkBj4JqhF","WSyX58ZnAbTsBUdxhL6miYYCvtroe6NgLk","WgUvkaF8TEvjvfdsy2pYzugVf34JWU7asn","WWPnuwkHJUmHBaM7xfNgbMwqnu1vkg8ojJ","Whd8GeTmgwwoRXHX1aSCFNps13GdsKGQ1Y","WRTB8pcHYVDqkzNWTLzUTu3GsXhgyQ8PMm","WfgWK2RQ9vYN48GUvh8Qd8DJpKLi6jyaL4","Wgs16ZU4Mks5uR9N7886LKyURzqGtjuPWA","WdQgX8UrGL9FX2SJVx694EmMikWDRWYFtz","WYjpbQXneJqDHHE7TfTRFFQZ99sNimT6n5"]}, -{"isUsed":false,"words":"suggest monitor cage purchase leopard robot purpose woman stand public ghost eight frost wine apology enlist hood office one spatial test sugar approve version","addresses":["WSXnA5rpJSuX31BqgbiKHR9qL6BVzmrS52","WZ6GP2QzQzSgVdsTUGwmCazDXhgNirtcoH","WRtq2vsDVTsFEvNWnTUEb9hKNRS94Co829","Wb15fwRDRqbGBF32mabCeuFudiW9X1Nwrn","WbcHshRYomQ6EZ14UgUkFQ4vjTiKHSJNVQ","WWkD8ANNLvqwkYomGikWHfrW9T5mzBQQnE","WgskvF2MqQyWj1kCNzLmJaKrAErEFpt1gz","WZQXVcSsjQR3nznGj3n7ryN3nG7oDhbmq5","WUWjvS9NixdKzFZNfdVhA3SgrLbLS5MYqK","WP2Vf95BGmcazWaJGSb7jp5DnHNphfMJP7","WkfBnd1sjqkBvcC8zFcnon2g4j2tqnGvvC","WjUr9KcwohtQ8PSFkAxTT23fSJjFTQtSRu","Wi5B8ahyhVZpBGJLYVuUPb5wqzV2MNLpTp","Wmrzj1p1y2DV4FwSnDKCGxyjvsaLq1C76H","WcXCwYjddpjdMZg2fRcy7syoGYr7ChgBwL","WeNaRaScA83MDQRATzs4hkkcjag643ASyD","WiSuYa4pjRHoUkivBsm7hUWKGxxkPecYxy","WYq7Ae2dSxcQczEDtdhQiUXAsa2FTpGZcB","WSbcMgb6jFXzLwmL7yGyHfcbpRLnoQ7fX2","WNwTLLC9fYE3THdiaNEpfQeod62mvuvw3c","WfMbjrdV25p6EaW7bsiyjCZ1RxDar14AVH","WayJXYU3Co5HpX2RNY5vEaKFSaqqNfeBXN"]}, -{"isUsed":false,"words":"give gather child already tourist front switch sorry vessel seek among duck biology educate tattoo wife street noble loud gaze scare desert federal dignity","addresses":["WXhUzgqjQffZ82k7u7kpacWLPgs5VkLBD1","WmZh8yapXwV2vfnaSXJBVf6Bfq6hd73TLF","WdamREJNZxtoL3rHbaWjz2dxsVooWJQDh4","WWBseWXVL51e3dF63ppxoeUm1wvgHMw141","WQfMrhNWK5wWckAktb4ttKFgpDrjXEK3hN","WmTz5HtUsoKWFkgFBfnoFev3daSmpL6tDe","WhKyHZjwMHc3A21wUBsozUbVuXr4vZb8yA","WgJss6VEsyNqBXLgupLzBoV7eA4Esf9EuX","WjGbSbgnijzRSVqXztPd9yP3wUAv7y9brU","WkVFuzW7YPYsaPvJQjTjGTMF49zvicCFE5","WPoNiqoiYMA5U1RfaK9p7nNH5m8tx2ki7U","WccpERK4LhkgKWHueL1yUwM5kMNE74546x","WSiNUK3iExiekptDvpiYLDaNo2bGQUVGY6","WYGaWKfyHKzCrjZ395wWU4NbR7rG5Pn8SE","Wdq1MKEAYn4woMWtZVeHdSGtrfX4mJqpbb","WRGqvBWyfKJoLUanmQo2yGxCGtXfi8uxzb","WkPUJriwoh7YUdz2w4Wk5Ah2CFVv8NzayU","WRWbKHK5QvubWM4wtGoxF55BM2szQjjXaA","WWeyGVcEy7htp4BjeBbv4grqknF6ePG2fg","WgLyLd8SSMJTBRJQsoXA2QD2H9T71ZhkVC","WgrSVzFXfNQFg3LKprSvBShT1LaHd6e61Q","Waf3RqRPriWSDaUmbHwAzJyux1aXLUu37v"]}, -{"isUsed":false,"words":"poet shaft turtle jewel crouch fitness mule machine spend income drive hill pulp indicate adjust drill harsh business obscure upon slim else border fence","addresses":["WeU9ELfGd8hXgGJyGnbWXivpQDhaVZeqeT","WU2vNrR1EQGtdWHemZPsrSGcWMDaF1XfR1","WcfM4k1DtkAgbspVhV6umvymHLgRCHrJXM","Wf4M293VvQJw2H9oK3AW9bvkGrnBV8vktU","WYjiuU2WngkpaHkFLbE1d1v7qkC81GJb1Q","WcXWfpWcuTXyvxU4nrTuxqXj9Wf8tLUpML","WhvKKp4khx8TktXovry1vjShXD8greJLVe","We88Fp1Y8j1UcBN9eNRX2mRUXTbquaf2iU","WYpKrH58psMEMmbMM8iSNfs8uSGuwWhBE7","WUziZyph95mytwsqv8bRJEyi6VHhKiXLML","WdPkag9ZHLCeVg7mdrGrRmk2NT69tYSKUw","WQRFap3v3wkNuZCGGWW7SL6KNjDGv8nPnD","WX8RQSyWuThd9sFRgeaofodsjnYPWRueVC","WbkyqtxMz4tawZzfp4DEfSbLrVyJnVfRZc","WTvHvWsBSLafL38fZEoA9PFwE8hV3f6Ndj","Waean7BHGqP2aqkyv7ZcN1JTGRodQhaZB9","WbhUtyDiiooaSTiM8E5cyafZZdSogxBJt8","WWSvjeagacHACKtaiAYcwHwA9WKwV183rJ","WX1FLUVbvPYHEGvSabkUj66TLh2T8WGham","Wcjey4GuqvkF4BPYb1KiVUgeD8D6xjdy3L","WmxTfAQ1Hxk8mLzEuTw6KUZ3ZAWMQQ1HoZ","WZgxfTxYar61ywto76nSMEp7LEo57o2yw7"]}, -{"isUsed":false,"words":"utility argue web negative proof vast concert fire warrior lend before swift neither connect calm ladder main angry thing hope human fit alien hello","addresses":["Wi3zBkNSXdik65uu8H2mUtGBXiz5DR9aN4","WaDAJ1zJMQ63HwMPnJsSqBxtJwJdmUHmfF","Wk3mCe4eQ3wGrvhrp7NBSTzCifneDdspWJ","WfH2sAoWtSuUHXb96TWKRJoCrxSABALxyH","WVmMGwzMcueFTK4VwicGYMhD8rhapcM3tC","WcauePfCquyaaurW23oJtYiuG8ZfLwGmuP","WcqXMWFwMzMWgS5qxYLsSYGR6k7dW5uL95","Wec2Dy6ssoBWt9fCJFNm3tfpJLF6Ztwa88","WUYbACLHeTs61AJqyGzXuVpwKN7EhQKvUe","WgMAVGahknenfq2oaZBqtTPWQvv3sN1Hni","WdV38S5Tnsz6bKYLz9z7r6YwqHfnqchBqh","WdyYrqTyDLD82nJpfZduiNadvRdz9i8Sfd","WhoaaSfsHPb5rjzEDR9mDZjwAJY1kc3bkK","WgomivXexwrvvg5NKzvyMGR4UUfdFmZ4hU","WXT3dYQ8KFkxkpJ95p1ESY3oJNrvsyzkVR","WWS6TpUQ3V3fDtjfUBAuEjV71gdr3SQvNC","WhvMq1NRMmuDBitJE6ZpZHixjM1eQgwQ8Q","WgXNZi7aEFY8KTrfzN3SKQZNZHmzSckwyv","WXHTLN8Nv8Kn5f2WpBpMhx39hnP1BZ3bAB","WgMHw7ouUJ4VZhkDH8o5KEwnG3hcxsXQhB","WYQxogVPU8MX4ZfFge5Zaau6WSBknFTDH5","WPx8YPhJzCF2GLMovyExjBywv8z8CsMo2h"]}, -{"isUsed":false,"words":"tobacco cement ridge enlist plate blanket inside oven hood sword element fence dawn diagram sweet assist unveil lab outer stock hamster rabbit someone table","addresses":["WPGKf8EMewXy71Ta2ALFTq2w82FQBmQh2a","WjJVhoNZ8L42XECJKC5YwW6ahjUCX3ULqi","WZCYScCYALbgXYJ3qwjF5pH5SFPCv4jrEV","WiyBJG95rwP8HcsQKLANKBRjraE1nuaH1p","WidtXheSBkYmGRkzc6j7fPuV8QdmWBvoUb","WddJfVMSp7FwNC2PVmNjVKZ77jbchcECPR","WWdwZDmd6TD1gBCMptFYZhThQKqms2SieQ","Wkn9BXhDvi6kuDjKXVoEmYcauN4zJBFq3F","WPnE3NKrxdrFmYtdHDmjjMVeojTPCpk4MK","WdwywcN5mAeVJeUiNEKDJN3p4kZSobhqVr","WXdyUPrg83MGFkP3g8r42tkcQ6hQgiWiR8","WfSKVRN4QX2H4L4T8gwBUvKowAreRTxx8d","WT4yv1wEx1WVjpqjnix6LS5iiU9VRaHXwE","WXZjiD4mrCjVcEyvohQkvLFqA8JBbhtPyj","WQM4jGfefFFY7WGgWgwJ4sLnLydQVFqr5Y","WgWRaHeUrQbjgy16TPDDGyp4nogwpFfZZp","WXmSgoXG8UQoeefP7riZj9WQzzFQsFmRqW","Wj43j5WXyeKs2H9rcpLDUGDVmPN2bi7f38","Wg8tqUouRjnjkNb4SvL6RLgHGJWwX4wzaM","WQ3fdJVWtw79Zk9cLNvni9SJARBs4A1mw8","WRSBCJWQARcrd3TMXZCH6e6TcnK89ANAmd","WfwSDX3cP6L9DoqSDfMFcLNCtGzuYRq7FQ"]}, -{"isUsed":false,"words":"dove slide thank tank weather secret behave pitch appear museum asset seminar wood hotel excess toy draw sad isolate small champion jar ring vague","addresses":["WeUN3YDLAZGKAPc9W8ieqa4KLPq4XSYFdv","WVYwmbKNuxkHX6TMa1qiS2PSk72LJK6ofj","WXNV88YQXBE4Jsm5ChBBRFgzpUsJ17euEh","WTDbwu5s9hKjVfB4KoDLct5uWzuoA3L1qM","WiZGbnExAK5HWKwGnn16n4TdFFWW14NrtF","WkWYVtBmvQpJz3sshQgWVJykrk4uTfEtdX","Wjf6kFUdTgDxHKNUgd2ZSCuBpNVEzbwJmH","WZTKBnk2ujkABQiyUXhBTCYA3RNG4uhYir","WYx171BASta37tkonWBuWHr1ARhQ8UKZWi","WmAPQWwzG9zrHHaGFNszPaQB7wnoNWG2eu","WmqNHjwNVTXKyRvgH11gnSivp549gZUQe6","WVXaMC1XxrGWu9s5nEhS19REURfgBATvsQ","WVVBayYhDiRhsJDegMwh3uM85rqLQQZb1o","WhXbLsRy9Z5mhUhp4FyPhwgw9gy1C3vhwA","WSKQPmCsJjtWqnV53cWsysfT953PeECSC3","WZjDMWQUHXzoQtUpFK6g3KX8mSpd5yMLuN","WYgwZjUBe4ewf15gSKE4zh1iDEyadqhp6z","WZwBcmvnLFTRJD8nhKEeU6iPrkrTDXQqmJ","WR61uGnoaNMYhWgjBK8ky2E9jCrbtGqP1c","Wm1WdJ9fbQ3jF5Axas4uN7UGSKHdT9FMxz","Wds5icfNKX72q9UjX8DqMHRdZzAK6KgpP4","WidWKkYHKj4whkRCyYZ6DdvmtzGjWezdVU"]}, -{"isUsed":false,"words":"brown imitate floor solution valley little hotel canoe panda math fiber bonus game heart camera hard estate someone fruit pig ladder arm little rare","addresses":["Widubk4NEvEn1T1bKPSphgEvT5ouq89brD","WT7Gs5R7A1gGG8LbQAqSX13QEx2G4CBcWq","WRRkj87cj9qpCUxRcmPkeC8HTPkJDA27rh","WjxwRSwjqeRECB84ESBGHLrqnGcUyERMQj","WYKBMbBkNg9hkbrpwdB8NyFjyuNgZKbaU2","WRszbakk35L8jLBcEFvMENQcdE77krU6b2","WWvVtio2FfmxfKyoGrsErguAY5zX8Sx1k4","Wjys1WPB1DKmBoRcNU6g2hEWEukKAVvrxs","WRnx29c7qAZjb1EhybEemmkxL7UgrD5aXX","WduPDXPe8CiUswCSPPYCRjVz2Bu8jqed9Y","WkpkokHEKieovE4jNoDvPD9SpfVikWDoCN","Wg4EPFvTF2XXcHMgJH6MN4mYXibkHGTqGN","WjHYLKk3zX7qSdZPSgm2iBbm7LJ57aBZNH","WiMxvdYSsUa5txtnPy4HGwJTuTvg4sagFP","WT3naKoQPwzSoS1mZkahQ86SpbsbaQvu5z","WT85tAmDRug8hwG1BNSTRjfa5x9xoqxeNN","WiFYzkNgtYK2BtBu3T1avRVTRG6XjuFaaP","WZdm7Xbm5ZD7MvgETRAfxLjPo92nRd7kiq","WiAPXwCYKW2iAv63Qu8yX8oXuaDvJZmSkK","WQtLM1gVFDz1KjmzQm4Wh6GouTQS452d3c","WjvQ3oKDF1HFH3qM26LUpfPPMJ5cowgjXJ","WXckuFdPBfq9SwLBmvKxqDhSJG2WQYrgdW"]}, -{"isUsed":false,"words":"supreme only ski cost permit gown foster nut already disagree grant moon vacuum fancy quiz vivid spatial erosion goddess document grocery gauge wire family","addresses":["WXzm93QMbwyayJRYbZLWACe5Gk7cVm75WX","WdqCXdyhsDAMMHCt6Q39myziXnPuQJyibJ","WXpN7LqcE13x82tB9s6KT9jq1E7V79TVnw","WSttWQpXLKZHxAPU9sS9Byv1bsvR4fMwze","WiebTzWztE84exJUwnbAnEbAdDLPh7ECos","WYj5DpWNnjjZyPeUeAeNThdykwFAhrx7Em","WUDQqRubR8TUdjGum9PVGQB83N5UEyFV43","WYo5QWbiZfzooJ3CFfNv92DqvqHJn45Ese","WVzz5qq35s7KrFHfb5BxEkvNGvehUaF6mN","WaXrujNc9KM9VVZZHpafWctGEAnadv4Koo","WNu5GUFNx3gnGPyL7p88UzjM7k8sFbhLLk","WXvcskG3eR9KW9EZDQAzdbTk36nD35iq5M","WYWymqVUSxnqREyUhgcsqA3aWyy8ebTv5U","WUC441JduQziSBTu9uVn6hoNm9Xj3pxxUX","WWViMrVXtW9ELb1Fk8UceH52h7MxbNxpde","WU6DwmrD7S7mnxQDricgwjyVp5cA4LixSa","Wf1RdxgnFbhFtNcduMw7qAo4GdQfRhV7Q1","WgRCb7RYWDbtnz5XWypHEmDzwrqqAkGYoi","WP61DKbJFx1tp9ax8XJtJ6GDHi8DhXAWHn","WWMNNvE1nt39D5UkPYFdNRu6VPaVZDXvpL","WZZvDP9rAZBkGKZKfKxQ8vmY4eb5VcxbxM","Wht6WVAV4gCjxxoY5cxKUWy6hcq1bpkJLG"]}, -{"isUsed":false,"words":"phone viable mother impact sight garage corn sphere year pencil welcome insect leopard toss stock wink comic fossil entire crucial burden balcony manual palace","addresses":["WUF34SC6vgy2rc4AkyQBSMERvpT8KzPSc7","WRVyN2HDfTFSjao6GZQ7e2PnN1RNrTD6B6","WXMedxyZPMD2FKuo4h1CTrAzczggUAsgmd","WP1vHeNyhHV2g1a8XkgsDBExfqQq1xJHHF","WQcSqYSQGm3oVoUSTes8QWWvu2CknWB3Ti","WeKEjPsWUJeebwXcarMdHTZmWyiUMVLx4d","WWAjEEaHHeYvj2YGwQDQQf1QoWsTkGMgo6","WUoK2dYEBL16veFtucYFax3LQC9rvnZ9dL","WhoKeMz8xDsr2xzmZ2dPx6tkbfd9hsQkvW","WXFsvArvakYh83Tq7cgCBFcdG4AfKf2opd","WdvNihd7SHKE3oVTXZCV6J74n3tBidSEvx","WUMfge72SDL53bvzLsDi272YpU6hKhukWk","Whd4cuBW89CubeSXDTaGndBVjzaugVJo8n","WkzsPSRnUB5Bx73oakP8HRqcwT4BxPmH3q","WdkCg4B9oSjhkyoJPWVjW3L1SMADnEUUeN","WkFMFUyFwFgiAbxvLniKuV92Tpu1qQJT6Z","WTXrTjo1sGMTHE2Hng4CF6nYh1XkrTeMsv","WW11rrB4GPFvtCiNuivwcZE6YXZYEbvfPa","WaPAERZvjkbtPdnC7oLWds5K3U1fnkNKWN","WXhArj8n3QRUFNqEpsBEA8mkScKbZudHcf","WY64zbdT5cvpBxGMdiLLKPz5JuGa7h46T1","WaLAeaZA44ySi3whzxajkucv7Dv3jU4rMR"]}, -{"isUsed":false,"words":"voice physical final custom culture image alpha auto differ retire ice file park field park convince inmate gain keen foot treat shift buffalo upgrade","addresses":["WfSkCuyswA1mpYkLr5ju9u1yirLzimS38S","WdG7omzBkFpH12iLbCNRskfD2orwahuick","WkBDQAUtfXDxsmCwwnKMmKvZXnoJ8PmHwz","Wiohkoi8p25ecBaz6ZFuvVrqDdYG5QP1QU","WX3mMfCrFimJvBhNpskS7qdZKrzwMGytMM","WVtsL3SExpb3ea5wQKewNe9m1USXeTnGfs","WSbRMybYmoDyssj4BfdfDQTNbdkrj3PJsH","WdGn8hwH9EJZ6VrqQ1GTxAxDGvGGrgA6Ld","WZPTbKr7AgtP3a6NjVDud9kN3NMNb4XCwu","WPMdSoxFFHpeX6bmgYoyi4PHX4raPbuDtf","WPtaEHR81oBVEvwVEDG1ff4WGz3CxsJAZ9","WidsUyRw4P6kY1NDkeceBkWaQiod2UzLb6","WRirdiANT5yt9hPE13Pm9ryAzaCdee4PbC","Wct6BeabbBKLdPdo2JbrVNaJjRWg1ffdH3","WfwA2tZbMmQjnxtk71PDoCBTmZUTBWnTHg","WQk5RaHzZvyDhS4WAbZqvjADfKCQGEMxhn","WhMNMcNBDd5vfzE6vBDyzjzubfW8bTJ5Rn","WRPU7WqDsiYnHVhDKBPEuoVn121L6JGBf5","WPLqpRcJFipAgVHs93eWeas8XvSLhnK7PJ","WVsKC47Y4UvtJp5JnQfxeTFC6VW2yxy3K1","WPwDw3MbiDdDSYmsfNNMFy1nYWXyi8Gq5j","WYdhFdPS6JBmVRavjqagcB4pCv9F4qKSYv"]}, -{"isUsed":false,"words":"bamboo anger husband parrot buddy crouch yard auction alpha upon practice stereo april column apple napkin matter kite riot know cat come potato zone","addresses":["WdDV2SfWFspPLWgrtrWiHim8B828VHaLCs","WQPQfUgLWgtTSj6i9fTQDQ9dCi7tV9JgQy","WeoVZG5N1n33qXC79DC5BkSE1bSa86osJu","WW2CNYEJXgajhFGGugKzNodtNt2dZwAxag","WkaTEffsGDNgNtMVuy1QQXEArUoqN8mgbo","WhqdU71QQhr53mKQN5a4irbr5m1URsJjhc","WZS8u9L3p6P1Nqa5jGt44KG9zMnbLMKF9m","WXGomTxgXWW4w9MySiDAUvR3eNaWg25aV7","WPiQBeXshDQ8y6KRdTtLuDKECTFEezTAJD","WPEEbMAj5cYTwsdHrPyYWD87C8tXSKCdLL","WV3HL4dxoM4JLmvVFGRRuodJuuVY4F1jbW","WY7S2TyYLc1JPk5GzheWwc1fKQQKYUkSQG","WdpfaKbESjpuHvVEQhMMTevTXaeg5etrPG","WZAKs9Lv1UBfqTVbQPPp9b2LmpswvSNfzW","WYGhJC8jXJZzWM39tWA679eKpyQ7mH5DwV","WRvugaeVwLYB3cjqTuL1c1wtjrxs8gzQZt","WcmZ3s5CJS3Cg1rRZ4hiGbjLZYd52G1Kk9","WV5ZE1D4CfhesrzgDsfzhscH6xbKTwnTXf","WkwxhUqHsePrYptZdGB1AzTZRh8suXaw11","WRLihW4JMVWpq9WGtzR34aKhbx8Wd29CmH","WWNtWZmMiBmsocFdQdVtgcCqpumVQGcv3B","WXnMof71zV7SfPsFN1yXTjBNAvnJXT2KHS"]}, -{"isUsed":false,"words":"scare private region pipe humor lyrics cool obey network near tone limb skirt ring color cherry develop bicycle add fine lend dilemma fetch report","addresses":["WTcXh41Nqs2seU1HzgJTmH5MRGuWoCJVEa","WVT9rpNzUkhD2FCh9HY7aAeDQtZkGrH2f1","WVdDoAWojzA5q4gViqkrRFvqrJc2WSjvQw","WdbSdyUkvLNWABA2CRyuNQ6eajHt7aKNB3","WVaJjKx51so8KrbUi9HrgSkCN5StdpwHw9","WdMX1RNHwAWYhzeB7pbe1jCPii9i5jm66z","WjgDwxSU45zJn6JMXYGZY6bGKeNacubhD8","Whu9CDScaoic8nWgSCR1wmTp1YAKL7LGgt","Wg3s4FekvGShAATMhkbhJ2J3eH2NdBgtit","WXa8xWmbB2jhdXC3gor2WR7sNaCPsRTFuM","WTVP1sASajC1GhTwG4uaR8FjNKpVGP3WFv","WYHc9MUXPjK6V8GLPCFDh8YWY7XtNBXYXc","WRXWDffLSraSLArM9Gyp2LCmFtTExY4htV","WUWvY3ZzCdzPzSQ3vbDqR1g2pZ9Qq7JnMK","WUQsBDtSh5i7E1RFc3yw1GEtMKreSSwQya","WhfnfkWmuzPUXT2yQqNgTr9pE7drKzAAqB","WhHRZCfAxTf3uQ3J5g6LAZ8KqnCP3fefNr","WYnMw3y7K8Use3cLUFepkxbXmC4zMrtdoB","WmyZiSRNXnQg2KvQ2fXJR4Vec4mQWCsBVC","WmEXWNVYwEmsRCiDEEKVnzytBEs1AwuZuk","WZJtPTxmJg4QWupvusTvRb6PYuv4GH3LBb","Wc9weFAtZMhCx751PxapAWnHeFF9srBHuL"]}, -{"isUsed":false,"words":"victory unhappy join fold year true movie law section market control slam project match barely husband choose cage great trumpet depth walk trash other","addresses":["WX3cVKzTdJeuNf8nq1AXRhckC7Ta6WxVLB","Wh2GTKac4QPbcKJYRB15TCg8jMAb1qTqAb","WbJYnf4YWm2y3JExv5BiAfxQcC8TSF6Xok","WXmTVGnCxCQE32RqF6D3c4UaeN1NRBf6Hz","WXmW3XcprHdsAeHwiPLnxyBUGcDsJfdGVk","WestNJ7rEgA9UsyFEJBPzhBi6QHm6K628f","Wb2aagS3NMj2Q5mDHc7CTWwo8Hz4sPGDVr","WU15xwxxzcMG3Es3Foixd26NURuV91x5rX","WfRc4Pync2AByMdj6Aky5jUatE9Npg2FqM","Wdtyq44m99myUPgAapkmfMBjSk5ExEMW5g","WQtNaBB7f1TzybVFJG2vCfeSJdrUn7Bmwy","WRJhNPuhWTJ32yta1Ykceca5hYDfMcRYrh","WPLXb8pYArFJUTw5iUVHK6zHgp7oxtpACQ","WbYxd7J3ot1vJ8C5YQZYQjActPEy6HdFW8","WTm7NBzJsea5oQpcN5xXVA8aBSwDLtmYhK","WRB3cnoP5XuLxwnUYWEKL14UvukYPP7XNX","WiRLr5TWPvDCDtmTCBoX44KPtAa6xJDXPH","WQmaC4p6UdFFQBZ3t5Hy9WYRJAfQ5gPf2Q","WkuXH7HHSYgXh9nVSiMiWpKfyt485zrkqq","Wh4qcxHzaEJ5kyiKZ1gMgM7kMLkoi5ED4x","WmbpwwRprdmsv8LNoqCx6rAFs3UtJRyivx","WV7CveVift6HoBb4jDaYxREFbv9g7pGp4H"]}, -{"isUsed":false,"words":"lake coral jar gym domain copper hello tone door crime phone garden sketch wave black merge airport artwork canyon essence forest angle sponsor evil","addresses":["WdUwatJUFUibaXcpWXY1F7T9N769P1R7jY","Wdzd8j6qW4V4LFxwfE7MZCgUKpG84C4rZK","Wdf5QQxQj1Fii76YLVwrks14Cj93cwHaXm","WUDkz1FyzoSYPM7y14ZfqsKEVqwg9r9rNC","WYefuwd3K4NGnAfYfm2wstQ5odnXj6EnKM","WdEA2JbLWEe1mwpNWMcTRuRDxQD7kpk5gU","WTy29kZdDst6GD4GoQE1cTaqrX8LvkYBe3","WYUfj31DrjaQe3GD6w2we9fVZrFzqQYxo5","WSEpoSqfsoZo1yMqybQZH94TK7EeNo1beB","WaZPzZ6VWLfQoU5BjMgEEpFjoHv5UZJF2F","Wapk4h597mgwbpauX799TGFrv71HqQadHW","Wmp8f8JNGmJxdg2ah1rTZHjkpPLVKmy3x1","Wc8Smcd2sS6KZDbwXN7EiX3qW9jR3Wv9kF","Wcv1enYVrRHSwugg2YgBrMkJsa8rsfdQ4q","WV1MQYRWKXxvp3pEWvsh3Wn6gdiL1kqihv","WV6rXkcH3cCUb3h5AyUpag3T55Zk7ecGWg","Wd8v2E9mrKZgaMeFzkAarFgAEpF7Ar1Vhe","WYhLfsUPFBcYQsvVGW4duD9Ayi7KtAqKs1","WitVsLJ9KkSGF66DyhBThBVyfAMsFZo5Yh","WYiVYq8rvmEW5jxctyVU5Rkon586VUse7g","WSkD9fVZRksNhQ3mL27zRECJTZTvH87B4g","WShkEeJRbhPiUhJNH84mBsWwggN9NoANJd"]}, -{"isUsed":false,"words":"waste south slot lucky flag bike bulk tenant episode hybrid ramp toast public beach unit learn brass economy noodle aerobic need main panel modify","addresses":["WjHz4qgWHTi9Cs1xqDy6N6CYCt6E5sEXfN","WX9q4ZWtX1wNE7zTNNpUTinxe9dWJMnepP","WP4vj46qxNhre1GmeqQtxS5yy5FkoNYnHk","WXy3KrQnMGeepABpjE8V3hXChyoUjASQRB","Wn1XNqVLEpu2dm83fNL2MNXJeCdGQDamWi","WegmMFWrQ39u6gsbEyrua2WQ6uKwSU9drK","WQhvD2s3GpbodkZuezLZ5LMQC4viupmGkh","WUwBVeteC2CVmcjckZChsAVKFsVABuwPT7","WeLo18i3Kt3GsunYLpxYx7UDFgN3f2vdQm","WUkNMi4P1RCtAgbZd7YBdiuRrsQsDYPhTv","WkGZiCbwdTrBxbEfgq5pDZwP9szXreCP4t","WZbB9fFDBJPCRMqKgSwFyyRb3qNu8jFaep","WP82oY4ggzeZLv9ns1AgfNjo6gdZRndv5w","WafpWK4Kcb4FeCXzP6GS131v11hijDCEWC","WULZfwoyzZHjEUCKWzY78tEXxFBqMSTrX2","WXGABvNiQPVA7U7xM9pjqr8U2Jvs9LdK7r","WQGjgP74cyRWAwZx6iNWJC7jbXsdtHEfsG","WPn9Q87RYKEHbwykb1GrErnjaFyCZYswyn","WSAyzKYeKmxff9Bt3MQvvfGiatia3hhwn9","WP4U7hFSGSgW2g37srzqSaqK8qKdvFg9HE","WQVWTEbMr98XhnAPxxpqGSpJrCNVwT9ZE6","WZgpPFGQndP7rp5Bx69aytBTgeWKiJgFwp"]}, -{"isUsed":false,"words":"grain powder notice giraffe inherit way sunset muffin sing organ bitter achieve lizard infant mammal holiday fitness genius paper buddy hollow twin space outdoor","addresses":["WYg98gKecpbyGdbCzoHL3pYe9h63RxSsv9","WVp4cYZZH3MyrsuJgrjUfCryk1iRbjDPYQ","WWPhghuCoodjErBEEzyBioApK1HmMH57ja","WPcWbvRtqSNaDA3NDYf1rvLqg8b9sxQUWu","WfSLyTS2695eDcJmZ8Md4YYdkvh8J4cFjk","Wj8LbVQY6syhNETVigD581Q9MkrwQJSoY1","WaFpojV1oohoqEzNicFpbmEjtFubStNYNX","WaBASuwy9P5tM1ZX6ZpxWcGJKgLBqYtr1P","WdpNZ4EyWieWbyiryxAyGdsuiKkymrf25Y","WUmVwApJLEkm5cU3x9wvSXYJVsk6bkYQBQ","WW3rEbf89BtdRZKcZkGZ9yvYegE92uqRXT","WYrwH8co4nqEJVQUFZSMDcfHBBGdrAkp9y","Wky1NJoyVUznPEajVRQKYSiNnXHVNFe9xD","WiBGT3D9WvBH9x4AhgV8JKhjYGJhiRxn3K","WbFRVZvu1adisPdqz8nZzrvkVYmXv1LpaT","WmrVpr5jJesbPcb9LKybtYHaY4evApF2J4","WQBvKYAjYFYnD7pVeLwVwyKcXhfX6MVaQW","Wcy5h9X2Tdi1G6wubKEGCVfbkZXGqp8H6B","WZGYMjsn4Qdmdb77XnNWHjjjgeDnBA2tyW","WfdMJi5Jbzy7KTjgLi83k4WwedFyew4Hnj","WiBz89tBubEcvLPJkdSj8Lsxu7RkwYXd5c","WUQoytvUb9cqnSZZU3ESi2UaieVBN1csTs"]}, -{"isUsed":false,"words":"almost twice vendor option liberty control own joy suggest market trim travel moment session there lamp salad notice gauge diagram merit siren move inform","addresses":["WmwETzLWsUXNpMuDyjsp1871n793WmiB2w","WSWnV4AjCPX72USvcFER3QVACYMjuB48Tf","WY6o7LprTwoRwpWF2smikhMt451N8t6qyS","WeBZ2hpzDUYQWnWL6xmbjfd3vPhohppLdU","WeLBABAa1hwC7PxYsk7S79PSuAb2Ltuijs","WST8c9YoDEej5UbqYGRHuNxd1jL4bgpmNr","WiyMhFe34UwNFRGfBvjkL8QkCGZWAgRuUs","WSMcdExJMe8msWsRX9EbzbQN8oRcyjrAzc","Wd1V9x1HohYrXG91zrak7zcfWXahfsEskf","WScZmaipVR46PXMvJKzXeAqTh9L9mqV9Wj","WZoWYpba27dAow6xup3knbE6jmSDAdjDsf","WmoFXZojDr9mnDMH2ukkZDQhqYPj5gvyAT","WPHE9ZJwoqTmWkrgXQGM75NvGgnkkS55PF","WSojuSmXL4rCaKV8jKvLKkSMqJ9PLooXNA","WYCwGQo3DkNBKUh3eXNN17yX82uXTTgFVL","WXJvNzMFWoYsDrhi9vQhSG2u7pjWdVBN9i","WTmx81LjSNB7QYdKVGQUwF2XV9YLdjB2ms","WdYpnMTecDnRAbp8bsjt2yTbdG6XtqxeSU","WhUB3xjy8XcncyLAyLU955j7hormnM59Fg","WZxd1fLJPteStpMLSqegN144FC7xHLMu28","WTfhA2RsREsTV9pmP1kUMEyUBpRAXKTG8G","WYPPnQEtoBF6VrrHdj6oimFTwjMfUFHHFC"]}, -{"isUsed":false,"words":"opera panic enjoy clean capital salt degree few news silver smart lemon enemy visual stomach tilt smile robust dragon indicate forward steel disease despair","addresses":["WeMSBnT5yAAnJTohmCf8W8gxJLDiR1WqJu","WgKAuS2gCa17R7zvZNT5ccd4incKSGhKUq","WiKTk3DKxsAFvQyUB7QDLkrzQfVwRSgZ4r","WSAbGWtcBY7b3jkx9gAVNQYzp1Bf4t6J9z","WZEhWsc2Qcum66fRvquGaZ8z9tBT4M8vnY","WV8QhXhbLJ8JQvDoc1nfzRpWnALBSAKLmP","WmCjT82Po167hhnUf7KoAyBHnn6wSMmZCj","WPeZYayQSsoT9z5KGyfTBti8ABKYm3d5nW","WgPP9WLLvhqG9MdAjMcHvra714EgXRVBkt","WVMRJx1aSM8FzC6VUNSMLFcycYYT8fJtPn","WjyrU6EASf2FA6eyj9pG7RV2EWBMCx3aeD","WSoAkjNWRMxG1qMuPAGxAcV9gvipNGjcbb","We2a51Q7KniU9rWGsfqmRKe4NCss5pr85a","WhXfTbQH85i4kczp5HxQtcnJq3FeDnjvNs","WcxSzneES9tuJqtzQbo2qM18dEXhcEvCMf","WZSajXypSNdvLy63DDjB5hEqzvfsvKCokJ","WkQ1p62a9v88nFetzxNk5sY91EbkykD92f","WRxNg52sZfS1rryu4XvmzsaGSuxkASvg3K","WYkzknGKWfAZwVBdALpnkKbs24rKhnbxLL","WaGXA8gJVXceCoMkk1iCZnkVeMUVamwZuY","WhpTJR4SuwqjfzpNjy6XFddY7nKVAUanXn","WNyGoJJ75PpzGDjw61NeduTqqT2QG18dug"]}, -{"isUsed":false,"words":"agent depart monkey ankle inner ozone employ excuse fox crisp invest tired vapor music sheriff edge side member exist mouse track soup dumb festival","addresses":["WUFvHsWQxosddjMpey3nCczhjR2bHPmi1w","WZqXiGercGTti81Dj7JBMt4Prq2cmeM5to","WP8RZdwK4ToKR6QDhPB8wKBsd2vsNe6QZf","Wc8qM113tHA4t6BpFMUniv4g1YvF86V2pj","WXw82UFxEad5YJqFNmGsG7hroqpMPzQChz","WgTSufPxFA5SZNog55ya5jbrUaYs7XDdCX","WfcWSYxUMcCcvZegiYYCnMjZLZEsdYcMiF","WcUTTCFt49FpXu93UTpv5ymd18xvkoJfst","WfS2Vybgp6rN5tvDLdNM3pWbkt8emcVFQF","WmwPwKjerok84PFS97LHTyqGQKUNcHGFAd","WSueaRpC3UL8dVt7HMhi8x5Eri1YZc5nnH","WgAs8fvDs8RSQm8H1VQR3qditAm87uBaiv","We3J4pCc1hhCh6pQ4PreaoGaaHxjoufnAg","WYKe3FGn9XKKUdFQwqfRvRzxF57Vpcemt6","WhmK7EEkssuSbdp4JsYxGYYm8YC1BKndPL","WUV4uTzaTDkphCF58QU8TQF3mPz137TV3N","WbuUCVG9BgfCs1FyQwLhpptXSVPXwU3ihn","Wkn8NbSqPmfLyM8RrEEGqqWXDav69BNJXc","WNnF8TmrLiJFimVih2w4DQghpoejYvqqYN","WTYjGUHsxk7ckTJBbU4da98P9WQMQeTHEL","WhSRVVaMb21M7STsqdB4pBjiKvhoorHNvF","WaX389cTdLP2rdWco9mQ6Zi94mVoJAeZqn"]}, -{"isUsed":false,"words":"ivory upgrade game hip cactus safe apple pottery inside congress cotton strategy solve child april sauce ghost erode risk devote silly quick walk series","addresses":["WmggHdTEW6YtmYrJ8W94gPB14SVcUmUR4T","WeudQ41Es25w8cjwuz7CjFTdMGmbEqWKd6","WiWHrsKQv2g863XP15e8RtG8kNMidaUu51","WRAginRdZiRpqt36T1XCqaPoExa1NsfZnc","WUKL7WU2ZFWiCBcvdxWbGQ2t86gTJV1Kza","Wgw8aon1gAx5y3tNSeUCvKCkBkJYrETvjm","WkQUpmUxWxtiQUhy9QoAeYREe5ajYZcWvG","Wbh2wsanLjiTAags4TfrVoYuFNRWu4sufW","WeUwKj9EtNe82SH9RzMEZFmk81dP5hrpaX","WhK26jhJZGXMVZepLymNA8HNGZqXTqBn4A","WauohWXjSW5KENPJKmP8rrAyv5CbVqYyA8","WmyHAaZDQSCVDEpL37r74Ugv6pHDzvwcc7","WWNUXsPYhVQPGWMYjbh59CEM9NK5TkMu8o","WkWCHN6DEGrgVdbvdA33HA3RGYnTpcV9if","WZ31ggdR3F8cNVreiomZbZ3ESskJeNunqs","WSaTUBmw1QY2UN8j6dYASMMcdamEbwxocV","WVgb3BBC8Ea18fYXjJUKfcdyRg62ULN8SX","WUPeXHiW2uiqryZ3XdwKu34AWbwy4MwFaD","WU4pfnwYynR3DiNy2m5PSGBC1u7awDymPq","WaqmDjCcT6wwDoBqtxDZH55ytbuDcJ84ch","WZ2aKbDAdSQs8XzMqcHhwaKPWQvzTN5onK","Wjo6Kym6xYua1KvYPyC4CUZWpVR5ogkaE6"]}, -{"isUsed":false,"words":"enable rent become wash popular general tip lemon protect surge blouse coyote fire purse path miss regret attack cost little fluid shallow route erode","addresses":["WmH3i4R2kYYvzhLuQ175kxbqJVVvY8SrnT","Wj1z9fYwiWf3tKyRVdBQSVshnTsBnS2pD7","WVke1YjnY38x1CLfcwosHUH7swnFBCWWt5","WVWVBnFEwgYbH5V8gVVRr3TRRFKa8FR77Z","Wm47uroEa2Tr1Zz2qmPkRQr8URaquTsh6K","WRUsjtHbQuZj12fZwQStE3fxU6fVF7a58W","WTRRLDXkAH6ye6Vnhs5YXLrmWAzePaptk6","WXxu7RT7m4Zqyic9kS9TgTxkVMjEByvDcD","WWpnrRBSiX22RViLNDijB67BAH9qDMjH2g","WWVPcfYS9bew9Afice9qCHUcnUJ5pEyuSA","WmzDQn9jXGs4xiweLEnhdaZtpbTt38C8Hx","WNgriGpawPzosvsWFfuBzZRGmq57HvAP1o","WUtZnToY5WyqkY7N9ykjKuVwgvbx992PTb","Wi25Kq4S2BWUCtVbfdvprTTEpfQGciYADo","WmDzGzxAYdhkRWCjm1RticgvyudUDrJ3nF","WeS2KQpM42WSqnhM6uJbBPDpKpuexZAsev","WQspXRrMn1ssPZbD4x2XyeNtEM32kzsqTK","WZA63b8yamBtvATsad4RRLPKnYQoFDKSkU","WUhrmxKFnXgdWUHnQs5kQssTj3XCPKQckn","WhrVq1CRsqRULtVQvobv48eZLxCDAS8TdM","WYfkYbCGSQdqdC2jXwFMTTY7KRwymkQBAc","WjmA93g3pssHHLoKsPvmfCmqYyDRAFd1TR"]}, -{"isUsed":false,"words":"hospital tackle defy fire cheese attitude surge gap wrist patient elder twelve wing switch belt invest fuel popular afraid engine exercise glory unusual wage","addresses":["WhYaCqGX4int6QYYtRJzJ7hF4dUG7BP5vw","WQbh3WNYqvY7xYwpeEHzHMuVtY9UfJw1w6","WkTfZfRSF5EsxY4XbsqVvirsybESUjBRfQ","WkKk6zJcmJox9r7JgEP3sAHKXsFS8ufXno","WmLCnycNf7YpuiQPvD5vvfpUa4mooii43Y","WPsuJP2uRTABdRXvNYf8Xm8KqaHu8CdzKP","WPJx5YwNyzm1fR8DVhWfSgxr3zepHJLZt5","WZTT2vd9hPoconMVeMVauMMVmLCjWb1ybM","WjTH4TegvuB55Ly5U3AjVwHWwgknakvvru","WYhh3ZqnTj7qm1X8xyBgids9wTL1YFXjYP","WYXLvYoTcReeyMvXeBJs1iz6hUNUG8pN2c","WiMmC5EerAiA2GZxjvmnTz7m9WDcyrUdPW","WSDETepVgpLXndbx3u7fpJYGC4a138KbM2","WRMrXrPoPT6DL39XiFEiKxUBjsWzc4pydu","WZdP6YQBwB2VYqNGABFLDxTDcoxQPdNzRX","WQaVZFmZZsvQPBdk9iHP6g5aA8iWe8DSD6","WbKuVz7pBWF5sxYQRSak8CqJkaTsVHSBPj","WYB5J6PC2Fb2NmUQ4GeEGS8Cjyumd2w7j5","WaPt8kED8ZNPGB9DxZ4aJbNeXoZJPxcPfo","WiYuoXc7nAMuWvUrK8PAaoCeZPei5sZXaT","Wcg7A2sbJm6Xacx2YC139EcC5g94E2b3tN","WfFptxSFJhtQ62Hdx5nQnZ3oWfcYStAu6y"]}, -{"isUsed":false,"words":"major december forest floor picnic school noble crowd flip treat ancient basic opera quit analyst exhaust leopard artwork tennis profit endorse someone crucial hip","addresses":["WgVga64eFgkGpbiQNr6HnJXg38RGWSbMoa","Wci5uTTQp96C7e8g5BaBAKuVhbaGXPFVfX","WNqpPjzZchHgLUs7bzaSRBJzsQB1DhYD4P","WQj4PmgjHKN1aiA1pETBYF2LiGJtD6BUt7","WZsLBSeGzaEM2HMBQAVpJZAkwzDD7kGp2n","WkaAiSy2NCCcrV2P43XdkkdSGXusQkMFxm","WasHQiry95kiNGSKx1yrJsDQ6ZRy9BgfCv","WS29evksn87LVgj9XQdEFyDuXrbGNFmmdQ","WRtSVb2x5aPmojyUPhtPV9h6SvEDVK3ZXg","WSLsuHrV7dr9raRVJY1ntKF2fS1v2NUSZK","WR2wKZVoBD8zh4iPeYVa35cWwZhojPXVEy","WmHS1oJpTR1Sj1TDHzhKp4sWeAJU9CnUZi","WYWiCGF5FGK6oUDX5LZ3QBtgo6Js8NaQwN","WX3ZzLCum5ttrD4D2Mdg1yJ2TGA382FKYV","Wbin2erWt1PrWJoZqYm7T1Y9Yv1NrU5iSN","WRb7uPpwBRzpcPoSPqsGzhHHD5uw3Sdzqh","WgE44MP3vXjV58QdZSWqM6miNnyiCGRizm","WcMBTyarqNUcC5eZxL6zvrHuZ2chhKWVB4","WY5ZAMY847t2duyiqCjjEtS9AWNaZ3P9k8","WZJ1LTLdTFYhD3BE9d6iEpBdUhhZng5t4t","WQuGhHqz3uxH4YNG8NB7PiNVKHYxDNGj6S","WPQQ3N1ATkeRqvUSANHRyJVRRkdcfv9azh"]}, -{"isUsed":false,"words":"tank tone warrior enable access scout future cabin engage evil excite alien garage improve elbow story used arrive script arena scrap circle float pudding","addresses":["WZ69jCqXBm7iDzCsSF7prvJuRW2z7FM9ZA","WUFTrnXo9bh87FGUxcCD6T51g4gyDHtm6D","WdCQQ8rrJUh1HKbMWLBNNMxRpETtNJTST3","WTPjKpboappPdJR8M7s9YJttYok5bknQMq","WZft7mDp5QJwnMyZ8AMX736qvAr8P5tW6L","WQS4mBT9JvUNfYcGEZdA3bmqL573q5rcDt","WNrUzJsbGS3PobWz4KEfqYggqPEA8qZ42k","Wgr4gFZcaXcbcEuvefoJeMEQ7BbwB7GUZP","WVkeZoeBZLN5w48azVzyWTTCxm7ogwGbPq","WXMYkCZUbJYhG3UmmYQqK5Pvyy9oPBp4H3","WP6ZsY4fiRrNYQ2B7PwuxEpgmZz6eRPYxW","WeDZ9oCk5cAf4MwayejNqwCeajZrhek16m","WQtoLFFBHD4rfNnRe15TMYf7KBk618JS94","WgCa2KBGVCqH8x2t18ZdAWdAoNBvMDhT59","WgnQKqARq35FKGcbEJsvBMFkS7jZA1bMq6","WmHCitCuZvRB9BFqSiqmP1aBXho3mo5zsz","WhB7DkrVJUnxvU9CKwH7yfQsDtX8mhR5Tk","WiXdwv321ru1F4kE47myUUpqzhpZebXAR6","WgXqp1HUfQw4fGWoJrAivmdaaiAGL2thn6","WRPbtx1PYRqMSf8mN7Qn7YVtL4SLM313k2","WXPPBkCedxCnWnLe6Sm1jSe4snMecei2DE","WQEZwk1Tr1jTogCJCxdX1t6dJT2EDXkWJ9"]}, -{"isUsed":false,"words":"path start trouble thrive like concert zoo initial adapt cube include path security seven trim horse find pair street bench purpose antenna nasty aunt","addresses":["WhYDkYJs9p8aTVbhb8T4sNNzR6SrwBfP7e","WXhz3AW2E2TtCok1s6WLGQv6jpKyGjqC6y","WhuQd7GNiAwFNSFuFxUDfuLtFuugG5CvRC","WXC1cJMWwcgMsyP2Z2tZPJeuUSRSSd6Hov","WaWWfttKfvKp9dm5kxfHMRX88UVpjYGCsV","WY41xELgYgcJpoKHYnndNYDQma17PFaUjk","WYoDJMDKpsv3uknBiqxmYmorW7H8CyXdRi","Wj7U1VjhuPKjsqABuZEKLwGyf5wXgJk5gv","WgaUd9D6HiZBbLYJxZMzVv7NdXqhEyX64j","WaQuwY5GUKS1Sv2csdxNFaktYWEhLVR6Ab","WVJUsxe1AAEcXKnKMtkUT32z7sbrTATfqx","WZ5b56FyMa3B3xDFPfXdZD6g3gvNwNcYDS","WWhfJGRXqSoVGheJgs5LHYA46MRvKZCBni","WUCryJ6gz44gjAnhFFG2URXg6qdJVgiNPk","WhytvitBZEgp4NR27fx6P49oGFwB6Pf8Mv","WiobS6K1joJk5rzKGwota6uGeehexWUwmK","WPNQdPcx7MhLc89HtwTDLFjTQfnfVVsSNW","WXXU32FLpvrEEhM7MPtokmHpszJhP7Aw42","WYzGo15aU7fvjeuYouQbMReRtHnKYm46hC","WanyauMmUcgE2ACWzQDxjAJhsFf7FXVowz","WjiyxZH2nkgkR7uALBqbBU8QDZxaxbW4Fk","WmezF5V4b2XmmeWhTFeKMB3Kaasf6GAxre"]}, -{"isUsed":false,"words":"sister angle match glide lonely fold open fancy six credit ladder naive wonder pony vivid member rib light bicycle plastic prison gun gospel eternal","addresses":["WRbDUTwELCLFpor9QN8bJFZ9fQvBTAERmk","WP2oza5Jm9fSQZhVZLwfvaP45rWaEn1C95","WbZA6CCq5Uh8KtEvS1waGTnUFVW7kam6FA","WhxSxocyEDJorGRLvobnZeEHSPxXuZA4PD","WmvXQ8sBRbPkjmsKfJp2HaedaURzeReLeN","WhzcKK5fmg9tpQRo5E5zjPC6VzL7HD5SSx","WeDM8X8UNEBJovLbeWTgf4dSG6VNPM84Nu","WWLAnLuu6XKPD5tsw3Jpp31zB9j4Bamspn","WRdV9bztgEH8H6anwpBS7sqfrRFmKKwmF1","WSD68ehmVhUXFshGjiqiNVBa85rqe13ixH","WZKK3M3UegU1xTDU3D5K4qxAL6Rhxm7Upp","WSxQhQRhpQAkuyR68h4iqJp7qRYT4KazeF","WThSy5ipZSXnsDrGSq6PRanQ5mH49Mr24q","WdhzactovDTyt3DFGfYTzjURo4t1fp7J5F","WRtyU8VSf9tVjotoxhyLnHxYhmTS3gSRsy","Wfgb5Xdx7WaSZZ8UwsXFFg5Q2LYUwKTSki","WVDaEreWHc3K48292ZAst1KD6Waj7X6PkY","WUoH7toQ1a7Yz8BD9pwNQcMEcrnEVNAj95","WibNEuVcpFa2mASRfz9tezG3ZDyqvKv8s7","WVoHSdijZ17sczmdaJeuMHrEsbE1NUR9Sq","Wmr5AYi9sdi7gTsVfmQ3L7Qq8P5eFGbEmp","WacbdkSzpLy3QbQi5LrX1kukmF9HiGBPtg"]}, -{"isUsed":false,"words":"calm love tenant early afraid oval common system october gate school uphold double diary around lab lottery embrace cushion memory olive receive jewel maple","addresses":["WX5trVQ2WutCHFEXbexNqPNzUA6De8xWUo","Wm9zMZXYWSVERsc6rjEhFTAmco7NKZHZ5K","WQBsdSXXStSXpPc9rAUXYXQ3PMNiFYJFCx","Wb78Jj6YuHbMSZRVqJhQLiuohPA12h4RTB","WhUM8gYF1SWpBNhcegjFbgJGxAabRWkQTc","WhksLGPJ1mmu39KE6iypazZjwmbq27wczK","WNwdUeP7Egpq6tBQ7TaVQgRe1itY7uRBCZ","WNnbbLw9NcD77mrKfPrtZx8Y2sMgJjjWSn","WfV3TndTYGJN61W6c8MFUKjo1dWk5JbdRj","WeZXBGUoKUVDPySXgtZddrnGFRxmrTRV8o","WSKXYxcjoMaJY3stzesjsddjuKsAkDdET1","Wdhd76fcNSu4xL1MCYeaaXDnR7hLdYHMxB","WXgYhRnDddmKrwuLsteMqVQNXqUB6mtG7C","WeKFbgNvfyZfXy9zb2gMyLEkwrPLKQnYkJ","WYnRKWTsyAAbFsDkMAMtmu78GqBxZ8iU8m","WThzAqFiScfuh3v5ZaVuEzvC2TTwK9qT7q","WdaWYJxnJvHwyFgHYFAp9WqM5M8ir1bWGm","WTKearoJsf97gKTD8cMfXPMJovFGxoMhHy","WfJhooGbxmoBRLNCUYD535LN8A4kozyTHm","Whe5sfD4Y7KgrihjKCNdrrsML4FyqBvgxk","WhvYuZho7JjJuv97sMFzuUj22tT4koHm2M","WQUiBZasNLjRwyAaCdM4bPpfnA3ZNfn4aH"]}, -{"isUsed":false,"words":"warfare portion radio boil frown faint tag magic guard enforce ginger tennis base derive monster grant cricket gospel blouse game warfare farm chicken people","addresses":["WgQSRsHj9pkZQXTDhiAgSRnSLJLTPEgEGX","WYMBFYBSPk8aDC6DfmwPRRX1vfsYokKnEH","WRWmKveKTWgkt476PqLtMS4CprgC1pjNuT","WjGXjpEuzM9gvCfPiiy7rCbdT93MYo1vos","WcevjvzLtnWsM6VuWzc6DHH1Xo1QfxDHpA","WT6Pu1WuYNnvVecanJfqwpXw7mHN1iVh8M","WPLmb5MupUBfhASBJmMr2gvtPNCguAmUrg","WaQQLSAPpqZyUgzHgZxsxU4KrUJenEbhuj","Wgmy8ofEsmJ5Gwd37GuWBCMieVd9sazUeT","WTAHC2D9VLkPfdv9WFDRVXZrZfYYeXHVE3","Wh3NJKah9Kf5XfWmMgRyUY9c2BzQuEXDAU","WgyLrUbybhArR1CAAvjSiipbtrEbxpR7qr","Wmhyg83F7afF8uRb7CBtbgsrrJ7tmSmJjv","WmiyBy638XUShtnWjezF29JbXSvjh6T3GA","Wgqj4qqjtVvJc78UJ7Mr7dCJTkudT25amt","Wkb7dzwdbQ3iAEZqPqKv7k1HpiMAsTtMh9","WRhcfXWeXG1RA1W74ksxxbPpz1D4E3ERZg","WbhSrFdZSFjabW7P8qtgR3df9Trb8QHGVL","WVpqyBeWwcx5ow3sKvu4uTK1K7AaD4uKoM","WfezjgmjK6U6LHEspdw3NDHqs5PDVKudfv","WQeQeNNhVcJFanKztfMXjZpwHCNhYR9Q1M","WhP31sNq7punzLjhP9B9ngJcxgK7BuH9ZH"]}, -{"isUsed":false,"words":"ostrich page orphan tower tunnel misery federal amount spray jungle obey surface swing sorry click sight bulb ice dune shrug index dilemma crawl youth","addresses":["WjHLwy7SgJk9TDjLdCy4JwMozx54LzXrV8","WmGx4XUXREboJDgvpWGqpshkL6m5rbeUCw","WS1tqU9PM14CTBrkMUtZ7cbby7o4ZtJnQ2","WeivY1n6yiSQYuVGruW2xLVA2b5SWs2h8d","WjbmXob5ejm24HsfjXnVjuAnEqWWvhimwz","WZJQL7yNCoddq9DnofvvJRq2pjUmpxniFG","We7T23jTS6MkSJzBS69de9n5iiPLSGi5ri","WeFEX2rCf76ixYTsND4jWnhyC2kBr7oKwp","WazvAXctzArpJw2GaJqddpxReAUK7gT3kC","WXJDkKyRxmZd9Ghv5cbwMTid9GpvBzvgEx","WgohF41Dp9YRMbJ8KSVefHUw6RJ7mxyPN9","WeiSGH7omumhhpcGxRzYVFxiJRPtumZHXv","WZsmADkPuhwxUNF9cxtsGjeYAvrKKVn7cA","WjdfUK5KaNWoBkgh8qaPx5GiyX5hyJ46ru","WgaktTjBd58wds6aVQvBEXd2DfNw8UGKWh","Wes2W3Y4gQFdoP1BjQewJV9Y4G3rJp3dWg","WRmZHkxfhEPwucuTdFYk6aMqeKDjtbaYLh","WUQNDVcV6ezoY9twoVdetsPabPELzDSWJZ","WUvvHeR5TNjcYwaT2zizub859Xcb73CDbo","Wj7qVR3ke3dL6P8FnJUix1BBf7RhubS5wu","WbX7DeieK14MZucvKaGRQzjcjaQR4DzUSo","WeXAcL1QaYEgvYHeaYvAqcEdyixrPMMhnJ"]}, -{"isUsed":false,"words":"area quote myself swap program symbol country blanket tenant total banana say shed virus change chat diary suit reject width season ten blossom focus","addresses":["Wf1aUZ8wpqzrh4Qx1fyfJdDqpU2RNCifLn","Wmtk5ZYDSXWp8uHjCTMUV8vva83pxQQL2A","WPubaZ3mcGQDQZY5f8fmMk8h5YrPnJCFZy","WQNjwzo8cnmZKXiGt45RPf9SzhACWHwtPW","We2V8CfY1i8GqtnpDzZhVztCmTg7w564EJ","WdJokCRAssBSFYYQ1ym7kKTX59QcF3uChn","WiHqhpqEoFkGeXA27MwaJGjB9eLmDt5Hww","WZxr8rnM6RAPSh6eX6GCRujFscN3RPexwv","WQKB92YD4YmtZziY6LpVgxCTDjadPwBym4","WZNJPsom6v9b6A7BzhRmvQMu6Th9TRDcGi","WT7gDR1nuXarwuttVNuMuwaqkGoykKkH9Z","WjHNXJ3NphAMD39MZknJcKurd2GhMvE9nY","WPS4ATPC5LPRLZME7uWRThkfeQz5RCgSTB","Wfqceur6p1B87HA2yWNU617imborXMGDPB","WWirkmuQM8TtaH3cqkjgFR89VNvE1VPs7i","WSxz64KKQVZ9hKPUHVrBEr9uMmPKLoxu5e","WdqsE7CFHxozGMCzKjM5SQBvsW1DDn3y9F","WdGfmkipYdRHjKgFKTWu4becKjxVCYrz8w","WZkbCfUnMfYgEwJRGuUZUSAR55nF6kmAU7","WT97SUVEwfG7XxwdAn798ATBpXk2Te3usU","WYWJpwq6FFP5VRKVxLud7dXC7fKdGj1uN1","Wm6SzFXS55TYhbUqATZJRdesgqe6jCkG9a"]}, -{"isUsed":false,"words":"liar slogan sun shoulder opera cricket uncover fashion polar moral oil payment truth virtual model gate property shift point reflect ignore box garlic blade","addresses":["We65UimFGEAYNXNc7mtt8L9Qkksii8fTPs","Wcv3izqi7saixi8jsU8prqjZhwiuyHKmF3","Wawpyu4vbSSrsXvz8XYWkxSS7k2uGNxPtj","WNju3vBd19dvFfbzsBxaqgWbiXKv7gDxuQ","WPMxr77EKNY68Z3FgtT6om7QTgxZxjLAG6","WeZr9oQUfehmNsoJ3omov1mSoMfRsAyihS","WWHcVqZbVBkxyXfsM6MerkV7CdiC2UnYMg","WNkRETSFQMCVFcx64rR44eksVUPxtcA14h","WUW9KPe2fkCB1uksp9TyymmUxYnnGEaZkE","WT7oBNWzy6XCVtRaQ4m9HJ28x7V8bEQYWC","WRQYTHzEAFa9ZkYdAQC8vVWQNyocr8HhxE","WdRyEiaYKQca4rdB3cxFimRWHyVmjVSaqe","Wfde6rnDN26NxfHCvNBvMzw8K66g5U6jib","WPFeARweDhEcpS8Hstjq1mm1gfPUraKJto","WZcAtDGcJ25muGR4LEKgMoZDKQtMLGQr9v","WQLSnoXr5Vfriu8dXAtmveXXd6Zm8whwDw","WPBvjnhJXdru15d1H4SY8Ek7abYgbmCMdq","WZ3qNsCit4yHwBdYsos3TjiVHWAvCfWmq1","WmfVCoaViTr18kJpavJncPJL29bfjSweZt","WigHvjNkehzbSzXxYX3VFRRt7jmeBMd3NG","WXvCCAnafLSy9mSWeNio9AdhKHVpWd7sLg","WcRzxTaZoH3pGh4unjf2zDEchG2cpCCqZZ"]}, -{"isUsed":false,"words":"duck sleep syrup silent click virtual ethics boost stereo swift soldier cereal suffer music now bamboo robust dwarf impose energy raise view ready payment","addresses":["WXs1xdpsMJu8vWLcA7DKYhPzgcKdm1UwvU","WYrsEwazSEsgzmztCXwNR1Qf81YhDqzwd2","WPVPqBGf25TwQ7G8rYsNfrJyHV1fJaGGYW","WeqP5aikfBKjCFmVmhJrLiQC364c9spx4e","Wg2G9SoXS9C5Egh4fKH64sxpoqwKsVwHoD","Wc6gm2QpkSLEfHBT5e2LtNN6XBhWpLqCSa","WRvcQAN7ifhScGjwbaeP8muN1xea1QWE6x","WWAZSocZPmX6T4wHU7d2vEEHEYnSvWjsw3","WQRzns2X4fvvbXzerZMqDEcyNMAsVZjZaA","WdBxh2ceXai9KKH1tQ4mSxL7yXpAVuMRSx","WcUFU16oByCvp41DH4LkNvMmrY3iFVDMVC","WQfmURkfXHLdze5n8vJ2bxoFsDuF7xRvs3","Wio2ptBoumpsDTZQoM7eDco9rxNeybZFQk","WQ3E7YspdqDNv25sx3m9nG6cNnzS3dz9d7","WUDFBLYrXHKCru1ufc8G7mq5y3Nk9hu6Mp","WfcAaRzpoKDMSBWL3toGUCeSx5i1mQNwoU","WTZ4Sr3C3KAeVb3muxzdWo6SntN4TKx6qL","WeW9KFVmvbVG6xWHBvR2A1bj6XooLZbzRD","WSoFkRu5eGGTPfEmteFcz8AHRY3agzgy9a","WbV2GKfY5D4fSkMHD7XMMxDtQKYHCfh4NN","Wj9QLnqfKtM4Wt6YwQUnNVmQgRRL2JAsS5","WRZdN34X5Nhav2yBfqk1f1HY4a5BA8K6Eg"]}, -{"isUsed":false,"words":"clever box strike kidney aunt firm way mean spice pipe scrap gap wool connect damage auto learn scare grain resemble cable bone gift interest","addresses":["Whau5WrShA16hBtbNoZio2dgfqsygG9LMA","WdrNSQiKT3XDjGQ3KDmmPsuJK4w6TGYp2c","WVKuy3gBt3FVzwPLi29fHFN7zwHgdVsDvH","WSbWhKvWBeBPwa9A3WK5pBM7Gh9tvw5st5","WaLzsr8PiRzcRXQCoeM1xX1nS9XqDUeg6z","WQDjMJMGjS6fFmsBikS6ZnSZrk5cjf7S1X","WU27KbL8hGc13JuFYYQ9fDpaStKDJUmpEY","WmQLsCQDbLyzVviBzRnNRJ3Zuoe9CLzbk7","WktmiC6qSWUMGoNEHAxgR9zYUA1piLUxiu","WWzZiqBJGf8Hb31pLhAdu6Y5Xek2hks8sa","WfZsi3P4c8b8zbT55DBUUEtBJkAr7t5285","WefuWpaZnAn9kuHfMDjrD4HHwe3Lmvf5pj","WeJ8pbB3f5cg8of6yeACSg8sP6jEbxE9wz","WmTpE1Qyiyep6dibzUoHB9X217rK6hfuFp","WQpeJzjrPTn3PR2A91DSpTdUpx1hgWvPc9","WYduD67edXTYmFMc6pUTykbZkjyi5mdswD","WR5QXHJUgXEiwRS6jWAbBUMafmR2eCyRL8","WV5oVhuDoZDU8AxdiuoVgGqxjoJ7Nh4Lsi","WjDWhrdPULmyEjBxmPBjw6seskCX1YzBie","WhWro2sTrgh3DCKBvoSmkkTr6zpPBCF8AQ","WmkBZ2eLvqHBdA5T91k4K891DPo5B2MFYx","WXaEZ9pjHmcZcYgvf1DSvzqKd1oa2ydAyV"]}, -{"isUsed":false,"words":"theory chair theory custom surface lake twelve whale convince car frequent action wagon quiz paper venture hollow silk foam power quality super deal lock","addresses":["WPHq1W3sSNvWxcUxvai6VSDKXiuJXDSDc3","WjSCqg7XgCfYSHb4jEVWBwrhK516J3nW98","WdpSXMxDJFh7P4HaKjBNRwYZTt1EJR1woz","Wfkvp4c9P6RzwRuywu9DuCxrr1CEPoVNdR","WcUssWg2GeuFN3WVLUWovormc5M4VUCwt9","WZMWNKqnfVXKwNfAcQmVzG3JQztejQqhA9","WRPWhxAefWaruqz9QLaSXnAQifhmpHk8iu","WPBfYYGrDQ4sJQovyi9oqnTzHGUEyFr7qu","WUdVVT2Atwi1PYUbKz22BdioMn9dSu3uG6","WfeU6Wnq6TpvPpNovXn9WS6SJgHDkVwED1","Wc71EufxDZST9wp4ZWgJy3CwQQLzXr2hFV","WZAyAV8sCp5TqVWQrWV5KYH5hPSbM5v1Tr","WQgHzNfpLrMkKk2Ld49F9RPtvqq8Pk1n5Y","WexCgiUeYgsBijGU8wB3eVanioXusU5GSM","WhBM7msyXoGzTGDCrBQCj5NeEAVX5ogSP7","WPRaNgtY3RjJZNJqwW9SrJa6BXx6uVpQ4R","Wa4KAWaGewZ1iareBJzQKvu3QTdkfruJUz","WbJNyQGFuqU6SztMfT75MYnkeicCDLTS9D","WgGcdEnhAGEdoPMmHvbDtDrtT59uShxDQw","WZ9apWSW1JY2oRt27ukdxyrzcbCyVroT5B","WaBLXvYoXM2qFzWm28ezhiqk71V558bbgf","WdAC1Si361MFcw9d7TmKhmvUinvdzh7wAW"]}, -{"isUsed":false,"words":"kick reveal inhale error lift bicycle eternal arrow fire absurd idea immense amazing annual noble marble mass buyer dice verb ribbon athlete seven boil","addresses":["WY5mgBmjrwMys6piTrYc3Gd5DMvjW14eK4","Wdq2s4koTXNT6whWbZTitpCHrCq36NSHnr","WRfHBdrWKxH9ZKxJnqJrG76p3bUgAzAWzq","WNp2EuURTMH4SyFqFhVR8YyRZdFmvxDu6h","WVkWt3uC6RWFXh5dRak3H2eDRYkEFfjyJW","WZGTCMjxt1EfpVyXKnTn1HB4c176tQVMQe","WYv1VX6igfiUpxqXx4xsMUGXsJzKuGWMgN","WWVwopE8Xdu3YZJ7vS3WZYzd1PT7jGY75W","WQT6C5hy89H4C6nBYu8cRfGPEPXAoKqY7R","WdxY7xYr3RgE9bX8mZZhLfaZnnfXPp9qbV","WeKZtLJptnr7teXEsVc8pjGj6ju8qAZ7uo","We2648SbgYu6y8yxaNb96WKWssZdZEvuYQ","WNmKkJM8butgczaP38H9wgsezTku9DJXDj","WmGFj1A9wbymPJ3iZpqFCadJuofMRmEkhk","WevFtFhzFXe1twWeqPZCzHBaCLe7kSzf5H","WhZqVBmurdDQpkv3yoWjuNGi3NQ87wjUZ6","WfNje9A98CFvfTzmemWwaxwU9G8GaQiUxm","WmGs3HH8tdE1sQTeYjeXJHSAmycxA7p5we","WmSwjuV2YF4noZWi4EJTo19i95JrM46f9z","WkDZd7JftcKtXEUi6KNt4oWEYZASLD3Qs4","WRVkywH7Trk7fuwvj7xPLB29DhoaBF8Hck","Wc8B8x41gBgkz2wn2o28sTzQWuTVqxuaC3"]}, -{"isUsed":false,"words":"find chronic rural quote pizza account pigeon logic black solid rebuild creek until sponsor ripple lady aerobic run claim retire come century man traffic","addresses":["WVS7zaAVFF5qVadu1L1fwmY1X7dfvmtKwZ","WVsn193yxM8URancAM2DRHKsDUho2syLhb","Wg5xcvNJwijC47UU9en7ZNdqg7XRL4mWSh","WThHwmgt9qSZyNQPwbRQXm9ohwQddzwAeQ","WiGQ2ybPntYTsEdVgp9Bb3SVoof2tegDdk","WkAdpV2Y5REeAr7jgf6rXBcqDwgyAUkRQ8","WgkswyDeNsHwKv9hf2zEDwZqAGas6eezMd","WWKvXRjfodNhkD1P8eRxgj8qTa1swy8fZq","Wej4ReN82CSGeauDWU73osoue83wsgtXfV","WPKnMzgSfzn9hd9HZZBefX5QTb4inKw7Pd","WZuXZTR65NBhF3EDdoCzHNWytpa1sfm18s","WazjxBLcZ3PhZDpoTJeVKsdqLGeCHjS5Kb","WehzfbJqnUWcfVpruxqD5RiBBNxKpHQwdM","WNjBTE46kLZp7dsVxLCQX2WEmd9ks3VVUA","Wf71p9KjW66zUvJCKo1wteFYR3BbX1xMsF","WRgUnUxNh87tun5WDiXpNQy1HYRLfo6Lmp","Wmy6EJs1fMFcQ9AqDvoCjdXWo2yAWTb43U","WPfbWoKg3185Nk3oG2FVrd2iLHtTp6x4dZ","WW8tXfg77GbufkzGJniQie1ATe4gax1R1a","WWf36pekKsUQXQosEYNoratujjKSH8mcYE","WVp9t54iSrQQ6vLCru5AWpUjn1YUXEGVzx","WdXnBCadA4Hm9VpREcovXzzd3XqH182ZN3"]}, -{"isUsed":false,"words":"palace toilet apple excuse elevator below spray velvet grace choose quality actress steak across rug chalk put youth kitten music process give reform horror","addresses":["WPaLPDrv6U4hRBt3VMRb3NsAA477o94Vnh","WQwRKwAFXMr8Qb9aQx5i6YatqR8ewgQsG4","WSvXxtjiCKHe1bPZQrXXoAv5h7ZYVeXNhe","WUHkXx1uyMQHtv94QbZNW3Cm56xYy6B3SW","WbxFa6dyTjhD7ZX7oG4yAEQWxzbcD3fPRe","WmqB4BzYPSnhe3fHcoxorRqEkRCKF9xHsb","WS4edDWfGX7FbMJXjTV2rXs1ZqWbpRgYMr","Wenn3b2MxfMXorqG2UXDnqEn44Dzd7fqVq","WWs5J2paMhpKnCsLijsR8uYG8ztSNUwhkb","WeFDeQTq4PtNGQ9WRUWHXYyYKShH511uB1","WeLRPVyZNQoknK6J1wMZPqv8APgoZUxJfJ","WmeKBLEKds9KPwyvBeQNGrGSw5yyDRtLZL","WiqxSWxAwiwUeMYUtujD2NeA7RLXQZWG99","WaKVQr6NzS6RZHDHk8QtczH9S1Zo8Q6vcy","WaM8XB2nM3XMGrJ24UMZWMotpeD4eWQymT","WVXfB9mgFbycQRikNgRTCxb3tBwim1a8WA","WSBoDbXULTTfcheuEiLqTjPCvmy2D1YLc3","Whsf9UvxKkXAFooVDiH72oPGFXwiy3K43L","WPNjvv4dYYxkFdMoTgMvkQ38z6JZ5q7PDp","Wi8CgirYSazWTVFjmJt9NNZHMgug6MJryG","WXxJB9eyHa13bASfXZ2tsVvaEfYHYApfMm","WXPoxZF9TXZE8VUukpswqDRagLZoSn8B47"]}, -{"isUsed":false,"words":"gesture fence tree timber sail field orphan flock ceiling dress display draft burden wild rose pencil fantasy blind faith moral know tiny report beach","addresses":["WhfnUbLDoRa4DdX9mbd6eZk7huUfYraN1Z","WRAPgTjUb9L7mNKfGuH6kTuQBaby9rvC7b","WZeTMUWGDXANHvwQbq27R6w7J8fa4NFQS6","WgNfryBKVdfcTvzFEhByfFq8uLYRcmumQU","WYeGsgBvDUgtWUSCBbjr6Y6mbpnGWNQHT2","WUhaknLqXU8U26NKPB6tmuPXEQcEriKpe5","WPN5gEyXiFYUV32wBiHmMnXhPpwG6v8iXr","WXLjGLxKs67ayE3PiYZS4q2eHmDG8Fp7PX","WZe6bWhqtAHDEftKqKRnwsmJJxyxEdnriy","WYwc3RHKpLs4MgFGe94CfUb8NavrheF3vA","WgoTfH9FWRm9mSLbRNcHYmq7SvQizvoYog","WgWbc1nLxraFkxHYD1GTV7Kc2du874EVT6","WRzx6xV5Mivid5LnmKmidmiZnyfs9BKXos","WdkJzeZeGgpENaiQrs5bkHqpmQzCgDMvJ2","WmUV1VtC16JuBb1n7qcVJbV2pP9mjsh75a","WXYhxdwzZiqhmqjUAG844aQfNs5bQYiEyK","WZuxv7WERErQ8scAuC5htEsXME8QTepeUf","WVEvRt6oWWdwDPDkLm3tNXhXyDsycW4MuX","WaqpJdEHZPHD1e5wCWRE658Bcw7w2FZFbT","WYegGR8wesbcbmG9Vf7NtW9WjNsQV7xesq","WdZwYzyF8tEkS9XPpD2hyhNEaFyeysBvKv","WhQwJKnhe9Y7TcHDnrRbPqj1THvduLDmPm"]}, -{"isUsed":false,"words":"because mind shy breeze insect often fun when occur sea blast focus coconut squeeze leg gain flock distance library hour amount divorce smart document","addresses":["WcSPv8g9dEiBhe4ox2NePTYhZg5bm1qJ4W","WRmmo3MdyYN1ZGWSseGWs5eSuY8xdeN4MR","WjC5XVSgCFcgoKhiYhcPnED9NbC1mSr2cY","WRkarpRaB9LcKTqDvDJC2CS3wSvnEZuHpL","WfP4tCDCbmC1oayufYmH5Y4snCdZSBspa2","WXFM9tnpcM33811QSooaUTXsxJaKZ9qznr","WgN9FeDa5MCi57K6smBV9S7po8MWDfybSU","Wdg7pK4FtVhqYTv4eijE7U4bNaJYWXt8Wc","WmF28UhxY7Xe4X2ksJuLP7fTRygR6eRdbP","WaDUcFeUihEgTjmRF68faoNBTNhpYrj48r","WhJqeJuNvTWsffaff3Ne3UWUGr9SGyChas","WeoLxncLJBtnbDHiVMvdxmUL84w2g7KQGf","WeKbosemHFLhxYwrLPFMCxCKXw3g3tEuow","WYD3vcZLSpVBdq4gnqTNZUYcYFueAgryfg","WWCHMfmipqeUNej1CatNMpZMfzAV4UsvDU","WcHFDyTProvLvcg9xRNDnPkLuhSfVw4iLD","WXgBLhadJusDezzuKSpMHwopCPbsyvCwn8","WYdkr7g3Aeum9cEYnqE2LPrzbQ2EM4ufRM","WVEFFCoXMtmewfUyjjJVDKiq63Jvth934B","WYwfxAMdjoZDNFSGQSszeM8uNzEz4bjHqp","WNjYdtPyMbdKyz6zg4RHH74sM1LN3NWiTV","WSo47HgoFrAFrEWYykcY8CwkSnYh4n73pt"]}, -{"isUsed":false,"words":"deny million margin change keen cry hurry pigeon seed dynamic wolf work twenty chimney rose battle humble outdoor loyal transfer fish slush wage harsh","addresses":["WZGozHTr2dfDerbJpGcaEQ3X9rg3tuwMrx","WQMVS9sJ9ENH5mvT5xmtSw3iPraHwwhaaN","WURafwxzYXHjFK6uj6xqybcyHq7oUYqFe1","WWXgRgQxaCCkwCjxH9FNqpTA9zaxwb6c1T","Wa6Ydh7mpHmc71acJ42Lm6CH7u57UL44H6","WQQy7Xn63UT7sYAvYwe4PFyKXbTLuufjqj","WPSJcpmuMNxCgcpzLv7358FveDw5Ur6QJ4","WhGSwqYgUL91MuH47FZ579i9fzYWmiiBtJ","WVVZrUvJu1c6bQEyxthS5dS3fAm72pT8CY","WVJfVdNtHnB2wEbfEvP6MEPU8EXGpNqmr4","WZypUDbkWZh4E3ikZEr13Eag2eHtuGFZ1K","WP4A2yZC8sVELpkYfUUYRDpHbDtJoavrkM","WTZMQA6Jxdye58BSBKzVK96SoyrPzRHVBs","WezcN128qCsrN8uSPuhhPo5DKDydWmc4z2","WR3j4kEGJ57acpN4gfhCQKcHzrSHQwMdQT","WTp3W5t9dA9RUPcWk6f3rYmA5z2u6Nnk3o","WUoicy51Kdj8baYAbt1MDWsU51859i2Fqp","WXJt15YLNwypJothhz9YTiUvMT1cPUr1YB","WYyCHpJVpHQLqPF3hLsSfkWDPgTfaV8NWX","WkXNUKhAQ8Ri5sxtcax1xjCarxUkQcSacx","Wgc4TtP8b7FhWEZ3TfbpaGCj8W8Wjkys2N","WcVztejvQWSKpuvxrdwjvn9GbyMqHb3GVZ"]}, -{"isUsed":false,"words":"case town seminar fix drive reduce junk puzzle merit fee true pear family wedding situate lend road grunt auto angle bring spin love old","addresses":["WSqU52ZQZ995Nouu5fXrCitw5TMqw8WxgA","Wi5HD8QVycLFStFp79N2YTr1gNij4pGwgX","WUNHffKE55Q3KPPh72EgGyhPJEhQVRBVdz","WiT3xGTtpXvdcNsxNhDnsuAvKzQTXV7Av8","WgDL6APriwThf5szwZt4BWtBzC9e79HAkP","WZ7VkGWNagXEvAPXyY2ce8wAUdkTU74VJb","WjWYDTHewkmkf96Xpt3oWcDzoZJiFF1fQ2","WZ9ykceEMnBeF7qJPPSKayRGDryGc4DJLi","Wm9tJ2kvP2ht6KRmQ37UfdgrydaT5MkMqD","WR4JTYQTaGZ7JMFKX3CbExNZqvGKuDbpU4","WSRLGDCtBT9o1LRbGNRWUhGf6a4pU1pJwi","WRqkvSP6NvGJa4g29mnZpooREWzPxky9rg","WknpDauAdRLiSeN5yGWcae3qB1ZUzgBN4F","WWPnUDbwuAemVip3s2z5ogKo7wr6F1qSF5","WbXtpVhStNtjGSenYf7og9rn7BacnY22vd","Wig1rJL59AaWY4xhRLXpyDJu49UzkY276c","WbnCuM3r7AfVP1j6FTf8cGr9pWkkAQPRuz","WZ1veGsYPkTYUsrWRY7h8woVkGXafNYuNr","WbmPgjw3QjvNAj4mMzxgZQeRLqfGtmkmeF","WkRVV5AkegAGw8NZ7pPW9kpKAZLGAhYATr","WTt6Thhs75CvzqYVZec2tg2mM8apJAtumi","WcseoR1XK2f2eTkYRfHQE84L6pzFB3PP9c"]}, -{"isUsed":false,"words":"tongue rely minimum rubber bone know radio direct excite aim original tooth recipe genre because banner same dose kind grid smoke enable degree mind","addresses":["WXfdiQXq3XMbtmDs11ZmRrbknKaTTBoX9e","WdoEpuLZ3hDJiGo1HKzTSFNp6x4SyQptff","WVy8VmdJJaRgc2EfUgVe4QDqNjqj7ZK7Gy","WgtFGr4KBgL42RANE3rUW1H3oQ3NoTDwkE","WV8qwB78bCfeB3n8QT1TLMKexFsvoXNhP8","WY1FahwjcYPJ5PyM5coudVce7HCJZMeXpz","WQ9vm92UFtPbpjyCZBBoPyGumekYPoNMer","WYYVtbuF89QPij3Bgd2cafU5nCdc8dmgCb","Whwr1r2GrNnrnMMBcEe5ATJANp9eDqbLk6","WgZ7Yv7da9BgxrNSgUM5HW34MdBM49bHrY","WcvW7ZwbESqqV7AKFdiZrTrk7JE4xtq38h","WaemsFDweoqv4TrFowvAEhufTX3wjYsMbg","WYpH4LUKjeCGabEnHsVwawW5cmMxRFLJuk","WavBxgydvjtbf25YQKsjTmTaAgFE3L4ZXg","WQSTs3dfZCNS9wGbJwARPdQXb6NSyjxiUx","WddfTZWWyavVetLW89Z9vTWs1FutPtBVzX","WjAj1nf75riC9yP1ETV8fCaTdHZJm8Jetd","WgsZe5BT8kqKuCsqusp5hhzD2t3TvhSDMZ","Wfaric5A2BFepF1crXfqC1c4eUQhXe683q","Wac7AHf4Ts72xdrE15tQRsqrb4XazagE4r","WmKfoUBWUepjt3JxpMfDTCBvPY16kqLP6i","WPmrWFZnXjvigoirmuUf8g1Gitdx8BHj5D"]}, -{"isUsed":false,"words":"sad echo mix business blouse forest valid nuclear fan budget oil jump story crater clever program office good flight sock clerk frost shop panda","addresses":["Wc8rB6LEYCJ5ZQZGmMJZcyDXrueRaz2dBZ","WcvuwUSiU6YtHHM12oJd9ztxaB3sRWdBbP","WgcMr2TxVNCB5xWnfdeW8V6PEuvbncCeWL","WmNRF7uevNHBcgME2X1vPAPp4ArqUCHGSg","WPDRptpCqyyivhjWZJnT22wMnJZB2MZXXh","WjzRyHRyFAhzL7eRM1fjQ7yiW8cVaca9zL","Wim3FwtoPqkRo9RpbShHGz22Q5DXiDopvb","WVx2tV6qzNq51GP8HvXLdVgvdtc9mzta3i","Wm5gZRANkgz8mRVkH8qsrcmmpgrtVMBwpU","WY7RNuA4ciogtdenU32yuLYjmsXrF7zBMs","WgTbec6J5W22BT9LwAZJCg7aKFT1Vr86XA","WWHsZSr2FZmnRxBoaGvRzcsnJVSqZR9kzx","WWCfbcSjFWNzswH7Qyv56Wo5vyiwMpGY5U","WUg2cbmWeEuev1PX3UbasyJWCLdnPFYMBw","WNqgE1r7MjnEkiC4FSz4AeraYSWBewyiLP","WUa2MhisKBBcrphGy8bk5d9NYGEEk3THWF","WQvLWk3iruMtDne9rW8m2UocrzSaobJBZx","Wcmfhu39jVFFSn2ePh1FNMv3oxTUAf3P8Z","WRXfyzL2k8P3ufvjrpLcpJShZLuEksBAZ3","WenzMVQhPf6ztJV7163qp7z8bvZyRcu1Ff","Wh63biYcLDNY4y1hVMAEVfyEFCnwWrzybn","Wea1UXNqHGFPaEiJ6SNtK1M3ZTJsX4QCm6"]}, -{"isUsed":false,"words":"glory goose unit logic cloth essence remain crouch major swamp climb amused certain turn real regret door second design skirt stamp melt crisp maze","addresses":["WV3MfuxwBmt9F4BtoYW4KZnNFtfuNAjocF","WZiC2bssV3mLBBEUY9XpUbTHH6DwDs9eeb","WWST3Y1m52V8VDGSzV5zUZudMtCeJuaaBA","WfZEzjL8e15e7qaz5p8b8CD2jVP7G9LA2f","Weo3wCE8SN9EkTGsVjWJdvVrxisQNoAgru","WU7PE1A44Y5hFV6pe4M5kdWXSsFRbbh47i","WfbvXC3Cfis42cvWqfqQR6w3kPvdnvsysD","WRgWXKpscdKnUxW9VZpjDiHibaMoU7BL2M","WcMrxRgST93aWYJBKS4NtAPvhizQKkcKrE","WQKR4PGV4sLNdQK1ygGAjJzKeargPQeRLf","Wfi45cTffw11UaHmWFdZohk5k6mNqU1RAP","WVpcCNid2Nz2fqjqwFfYGbSrjpvw2kcxw5","WgUtjoqUxKbr8NThjJZkgjKkZP2Codc2a5","WaQMaQLtDYcATaBrJXcZicqCCxxP5BaM3S","WQNmAxvvnCQ4ZZ1us2sehc9SzrTpRduHy9","WVfGkqAB5qNJG8jNB4bo1YzUFVL9T77YBZ","Wf5vtDpiY1uJrGoowLJAnTKr3HyLXAAkhq","WXxc2NYUrDMg2GVcWZ6SQbhTq5jacCTfFh","WmfenAtqCKkCxarnZ84vTSaFyd6AB3DWh3","WjdW9N2bmUQ5gqQWpJaFqWAW67f5QM2swC","Wiyspv39TpmvyzVMr8KEhscTd9RstSMCej","Whcd92WknU8XnmT2eBRAYAxEmQ52AMDto5"]}, -{"isUsed":false,"words":"start luxury book merry picture wrestle modify come organ shy diesel discover panel swallow hockey submit spring imitate slab adjust awful spirit equal vacuum","addresses":["WSyxxDe51UaaHrQ6HW6L3kGyDVSmdYmfMQ","WjiNVeuj3r4Gtaj8cQbhHdBZg3miDywQAa","WYN1dw4PXUC6wBkkwwU2CjgKJ1qH2nXZ2U","WQdpqsB1vc8caYvxHiKyz37inzRvKUxxt6","WWWVY2aoQzH71txPLirQSnL3gTCnXzacFF","WXEjZqA3yyokSJ37cUo5gscCbYX2hP9Mxo","Whbw1TbHUsjYNX54jnFg49pRvqk3Y84ZEW","WkBvEArwhEc8gYZfeL3i1JRu3q41gtd18M","WmTMYrToXoMmhD9iF5zp76bbKot3z4M5od","Weh32EGB6UyLyYDPTx6w5WikUCCGtXm1hY","WdrtgTjy4Dc7vSFe7ZpmKEEVkv12Pn9uz6","WXnqtYneqL6jw3WFdqSSscc4Cgx1AMWECy","Wg5nFz2pVDBKGnka6zMMvVkGfe5KEugL38","WgPTVcmXaevGiazoMbqEMdoBhGnXKJWFU8","WVDZREGQRkcbSKYatoBR1JFQwZQYijZKo5","WRUaAUn1bWASawiRFEQZ7z2vrSdu4znhGz","Wk7kHyzNWbV3YG7zBrRJsUX3F2zRe1ayws","WipRxbJZiruZA1UYrNDNCXrmBeTwn6TbVN","WmZunu1oHRLSpHzURkCCGCYVNXRzjwc2rY","WZswcewq9cRM6shnre9AQfYbJsCPRntBKn","WPMGmEiSAoh4SzzBMACcygwrs7DfKmCVyp","Wk23LfENFvjwKZUh2Hrn8dkag3yWrUwKWT"]}, -{"isUsed":false,"words":"whisper base solution woman monitor prevent cross inner admit version poet balcony attitude raccoon unusual leave scatter injury amateur year ensure hedgehog hood leg","addresses":["WYPBfW4N5QBvxhsPjtEvsX84ZHi9h7Ycvu","Wc8UqkcB5ZUsCtqeAJ9JJfCbvUZgxC3m5f","WPrYcYJsELrexDfpo2PGKN6XLzQSkMXdj1","WZZvGqHhGjusHJCv87VfLgeK5Kn26VKgyS","WQSpYuerhxsuhabWL2Qyic7wrExzbeF15f","WYCZ2oDLwGRKttxus8beUYERKC6jR6Gubk","WcgeCMAi71cR98shiHzYdsoLRBDG527iah","WTREyFPttAgPU1WwXWLsoZVfRB5bBw5bXe","WdgAMcxaNgwQ3sYQa2ctQgWBtvTHYc92tc","Wfae1STvb3V982Gb1we2akdxroN1JGP5Wg","WX6ZE7VRjQGJrRTZCWKhTmG9BiZd1gMapJ","Wf9xhEDBFvVgzxquKVwSfzCBLeB95ZWCKQ","WajyiA96B6BDcHQwbobJonKNLV3LuUrKKn","WdUqT7zFdinjiuj9nkK5JZsnUNmPSFbCNE","WQSKhvvc9WBBoQ8FycqqrsobaNAovh6DS5","WW8emWqZnB2KTn3mdAj4sr4TEBmgLKcc8C","WmniLh9k3n96yma4HXYVkRRuNxzmcAg8PZ","WYn4PQz76X4tzP1Uw3vpeR6H7yQReZC4be","WbjZgS9K2pLeSmmiftF8qPPPThiDxrjrH6","WYQuBQCTZ2HCx3jgWUkq2LojtKNSzXYVPF","WgMTym3tJAGYtyoC7iBshyTSP6tAxbW7FX","WfeDAYq2xQ4pVtcua1uKgtsLyX21jvKcN2"]}, -{"isUsed":false,"words":"heavy current mesh banner appear canal world where turn ask course used room sample sand corn test flock confirm humble diesel august nation better","addresses":["WaUDaNEMZXxTYfuynAJWBdomsscgowNxYC","WVn6vyqcNg9G6NiT8X2VWntzGfveMC1rNg","WSfjKNJVHPGmUyNwbEurv58V88Jz9rfQQJ","WYNJXbcyjWKGNDiN9ADyyGH5sr6rK7V5Vb","WbecLx2JrFvwkJohbkMvLAv1tRhUVAF39Z","WbNursQNeS4mbbrAbzibXkHhp9z66sTcVf","WRHfVQ6yugQmh8ozD7DshVvnhP2o1DiZ3m","WmjJqhH2edPYDqyUAkDAqAGZqM18LGpoCx","WXugRTTd1iE17iQh3hANtxrwk1aFuBGXFs","WVhg6fMd3zdiJSfP8XqL9b3PW91n24vnif","WdSpnVKXvqRdJzp4xKs6MTzsQim1NnTFU1","WcuuADFDrZ29mLjLi4bsfmHjP624oVWiTo","WNj6ybwofSDwSXYVXatfFcFZHxBDyYopXj","WaunsWbg6JkoXjvAw3evpHRbMLP87MG8Xh","WVmgzdH5cgDSqzM3C2AXQqrxvkjhbUKBxv","WeUeGj3YFTexjN5nqkjVNfddqP3fwqbzqg","WS94wPgu4ixZ9KWUuF3zUhXcfHdeiB3BAV","WbnK6pq3XTHMg2mEEwBgtWqvV132GLGXce","Wd1vcXSrYYMMSxoPZrnZ3Z3k4Cupms5NUy","WTyg4jBaMWbkVfDyd6TPVoCGjisUWQ6rQV","WWLbV4uvacPQrZs9mGeRCxbA14tCH4B3Ff","WdqUVT31CxuwQSNKHCQFq7DdKvgZLKFTpf"]}, -{"isUsed":false,"words":"cancel toast forget ecology return tribe horn mesh ceiling weekend fit style coconut injury already execute trust slide special portion mix law solid swing","addresses":["WffkpUkVffNkKTAUPSBmwXPUHR5XX9NCu1","WgJ5KS5vxwiVvNJNijGntupDmrZPDyFFDo","WdqgPKgmybWqQAzLFrQB1PbtdqNikUwct2","WcFrAgAi6vW4corUnkzBoGUeF393tbhwPK","WfR4up8eSifW3SzrrY3uwDPPeKF18sMoto","WcxoxXYU3gxvJ3N2T2vRBLDR4mpsX8WMCx","WR6iQ7bAcVrdEgDfD3djwgMZoysj9E8F7o","WTHXPVFcfStGJnjvFWjF58qieJkzEZonvp","WikC9psXQGw4YUCtPDDi7KaPGYEdAGBbTk","WaNfRch9Ub7XDozodSa7Vk6RQN7ZBhC8Pd","WXefcuggb5KaNwbdxiB6kNZXkvMab87eHe","Wmj8EeGm887y1UzrQAVWSdDndDhVdGQMEY","WjUdNgmqM1NgmbUDjkaHZ7gAg8W6ijoUx6","WaQnJiFnKRWETKtoEVLT7EJjApKFHchHEz","WczWiis22LkpZH6GcomJVcFDC9XhKwVYtV","Wif2pE2nybiSpgxJMVFEF32tX7UQun7RJL","WPZRt35USmLmVdpvM21nfxTbgP4BVmoXRn","Wk6Drtmhctm9rHcCKGwk8n7LH1LWpkVzWN","Wet72kXFUTH55LjNbSta62pdS5QxqM9AYp","WdTrPHgUDzBr6Sovaon8GV7K8TpvgwmRAX","WUyfX3NDRUBtYFh6gcxGW3VewCtf4pqjXF","WkRi51L14Y9DmbbK4WiCt4TnyF5Xc58JzF"]}, -{"isUsed":false,"words":"voice proud sample trap secret fan voyage clarify scout fog spatial witness audit wheat eight tonight hawk rotate switch wisdom tragic practice skin twice","addresses":["Wgi7ycVZwU2hmf214g5wFbp4VstAzz64wQ","WhkLfiYJG6axRksi7enRpvcRjgTgS8AFBr","WedZRktJEzmgUJ9ECjSFAswitMgo4YAC9u","WUAFoujiBn77J3F3eNmWwbPLNMQdew5zCf","Wg8DqC1ZT237jRDKB8mZ9BuV4UoVTrGv8S","WbJNgA51vyb4TMJAqx7K2A9T1J6y3UduFR","WkrYdds9oqXLvN6XaAHCHDkhqzKLQ2rJw6","WhFArEZQmLhNKpxKqKHqge1rYcfjX3FZ7r","WZdnazBRyAuzpfV2Cw4KrpFVt6KR3sHpUF","WQeXBMf9M6q6Kko4vxFDKFYN2yuRDPHiQU","WXfBJKh1C3728RW5vFWSa9pDrnADArzCoY","WSYfYUGzRyUCpu1FxEtWm6CAfZBReQkimM","WboRESV5d1fG23diFZiKiz2Hqdu9iTdK4A","Wifoy9hQ5T3nuLzF6JB6PW94hiSpqkNWuN","Wh8vCCEfPrH3U52JD1SMAcWoN7TaJLtYWY","Wc8DDYt6ugST5DVxNetfocWQpyt3XMwGbK","WVCfscGq6EjRgK6QseZ9BMo1nTE25gbFVL","Wi5caSjDNjrCEvnTDLZHtzefswHL45wC5L","Waf2AWdQWBwJY8w3cTHPHjQ97bxoTbuEdm","WayyTeWfPPCVenDmXnBBdUAzo7M8TG794q","WkzRH9U5XjNRDQFm4bZffKFs14BBWRj1db","Wf3vofXKsUZ6VaTuGS6xiyLUTyFHmncux9"]}, -{"isUsed":false,"words":"bright antique project portion test subject bird void direct merry transfer wood glove train brother provide pizza claim gain zebra hospital smart benefit slow","addresses":["WTvXynhxAEwEKnAqkKcaw3iGVVeiMcZKHM","WeSWt8JnL8oy7Ey9ZTX379jbqknZxM15Hv","WPKouxe7goWQUFrUjr4LrkhXSABttFT39o","WigUSwbYJp2ubH6GTg8RKoaKuFcpQTnD14","WdzSyusYFLAiMFUvM5EZxRNBcZHVyTfTPP","WgNhAdL8NsxsHM3DKMhudpuZsvo2Fdoidm","WYAnvcfFtt6Xw2FfDfEJu53q4aJXS5h6NC","WU3p131McPYYEhPNkZym89eULvfWtXKNTz","WXjmHWvEVTCzQyvndS81PzQgandRs1EFx2","WdbqLqqRfx4wXhT8ztWPs8VXieBGrSJT23","WijWE1CzQqfbgzmpMCRVpNdK6qiPqvS4xi","WU5xBDEmJMn7D5pU36EJmRE14TfffKMaNJ","Wkwc3a2owxJXZyE7RmoFrN7Mnz2eFPiyZN","WT4vpswkdZLTaZYGQxouG8MSpUFkKe6bBG","WbD14p3tMHgzmXXWRCJJCuHrURn3JgbQCW","Wh5vFaUMMARMVaB69unPwC6EXEwps2dTfC","WhvTp3NoUAoovdUKuBQnXoFJP6XAguZwBT","WZ4bya4uWzBGPEqzJ2SYDxM6GMsVjdQC2R","WPZw44Uvm4RS9eGSBwDwbCZ2XGoW1FV8m8","Wbtf257utAzXkHhVUeSso9tTGiRXcP8NM4","WS9x5yc4aArRR6QadKBut469m4kYVN1KiG","WiPTLsHPQAZJorvjZGELUeaaQcoTpUAHfY"]}, -{"isUsed":false,"words":"hurdle direct potato visual salt art omit spin lazy account section chair tiger direct unknown pulp trouble mad major cream salute audit wash practice","addresses":["WjkC1PZNNZ8dXsKyqkPRGXysKuNfDqiXoy","WdvcL15hrDYpuT2hSihyvM67CChHCyD3hj","WdBzXQUW45AcwXQDeLG7oFQTCgsrvqaHsB","WTE9ZuioZhmZwRCKx8rnjJiNohTS9xYQd4","Wf5UCkh1kKsJpkDjcAHzbC9tq9iXYLXMn4","WknuVpixtYuY5e2Qd32g4y7f5zGnr2QQSk","Wjabdy2mybW95hoB3p6epATT56FptSifDY","Wkr7qHWJxhzuCVwpFdK4ud2K2J3tquELmP","WikGtjG9LiddTwDf4JkkgU27tzMKofcEd3","WYtS4gwvo7vEB1DXMqHPdEN8WUSx9n4pfb","WkseSGcq79tDBNbRG4zfNSYzSHGeWwwazM","WUBVwCTSddN5D6PKfEuQnFoEvWf6Y1TAaQ","Wk5HeCLf3pxYwcHiboyTDQmSyTqDFen8Yt","Wb4DvUcej8hLK2SPsT8D8NshXMF2MJCwGY","WcZhdcaw4qB247BeYVPBKM4ZvmCfC9aXrQ","Wm4vVQLSreZjaj8g8AeJarnAsyQ48EqTFJ","WUeLsKggoTD19ccngxBQb8fpQ22sCny3aZ","WYd7dLPC4YrmfNAAhK6BrFuUZCbQAevXG9","WkrXezTuPda7K9NmPPMyGm3LuMdr2bjiRQ","WQL2kMjosZQLb5axz2K5RnhfVCNUfQuoMA","WQgZbtM37kYDRDmBHhDNPthigxLAmQ2hY5","Wdos2Q9sx3FnnJUuPTGWqyTP3TeFMbeqC6"]}, -{"isUsed":false,"words":"aunt notable village suit zoo merry boost work seek island syrup inside own disagree direct journey reduce blind kit hope cabbage tennis exile exact","addresses":["Wjxb5hUznLTGiTouJL1Y8E3HCQqtjzjVxg","WXuZaeZv7mzj7Fm7dAnS2hLjXsHaKK79jj","Wf4GLsojyfqGbEoborEN4wi6Ngoxe9Uorq","WizPXb8gJcnxDSbZ1Tow77pPF358fPi6P2","WbXn716btTAiVPsJNPoYSdVhuwNwa1poD3","WksooqnucY2ws4pzuykvupUw9FapQ8ManN","WP5UhAMfRnrXRFJsNsSVi3h3zmt6hJcu5f","WSZYStG4cARbGQD93JEdzhnpHrTtKY5Y4L","Wiz5rQ77aENtJbZ1te4X8jfwQFtmkCcYeo","WY3xHDgjFYB3XaAiutxeFpbShKye57eb5w","Wb2jom8hwS7JhNubpA9v6G1oumjtT6ZbrQ","WhZsxRduf7JPHUPfGjVcdkUt8GAn97KEKd","WU4xFUCbw2ZpQ24DmcnUzoJpo6JUxYVeuG","WUEGzMQ6LdNstuoAd7iAi6BkGvgLCXuduB","WRWdpXxt8ozRNLD8RTAuY28Y3WmydM7cyq","WUmesbPMjeUhzM2S3P9Hdwu11RxAkaxWJY","WYUYjBkHnNFNNtHCcEnwA4dARUMh2QpqQq","WWbwqWQGogn97SQDqNzC1RqZMzNWKJJbp6","WRXAvzjDymUUCwfCePrQkkXUKZmeTFrwg7","WfE2WLmmXAQdhfBSz6wxh2VEY8qNGd1TwA","WjdoSX1RNpe7jvxSAwV99x63AqgUBK119i","WULmVZT5RYhW8hACLFZExoKQV9T2rTo7TS"]}, -{"isUsed":false,"words":"illness draft sorry rough peasant truck green bachelor real fluid cinnamon search student coffee region enforce reason boil excite claw cheese toy forget rather","addresses":["WigN6PcqsCVed613cDRpidqQBQLAArEkRU","WdnA8w5ZhxPBZD8h1rcpgwFF8nocWczSmk","WdQWTu23B5eMpQRHj1C1mhG5Dd66XifAWa","WZKXKCuScz9nQE6mEcVGeEh9u6j1NA9iWC","WRRioAK2LAnP4tScce4iL2WZJJs4vdQ8Mt","WSepws6M5e5jbdGPbtJdqx1UfEL3z9SMPx","WcsEYdhUJPwb5fraVxCwr5c9gyiYEiy4JQ","WZPerGCye5ojuTFSws3HufG1EwgHj4en6X","Wi5H4tdojZzBp8ei6PEtaTS7rJNP6TUHoR","Wb4pubFfS6ELB1ty49DH8ys8bottpq51UG","Wcx8KtmsJ54egSd4MT7swovDKXSJmjNvem","WUWx3XTnSfWQ5pgj1Gv4E4p3BDc6TKcqCE","WSM2dvZoQYwJYyAVbxe3iizFsiN9yyS8Ci","WiS8WsK3DvnmJgwTHtAZvVTUr5Sw2EHvWV","WeQ8oMtPJfuBMt5FFcp6puoCjsrLLewLdM","WcgQJU7cEqskgzSwvr1NWY5UyRYHJPrHda","WXJLMvtczGwPZSchTJxdVsjMDpBk7spgA1","Wa7LDFi5v6jhvsRdvvmPnJ59WLwzMUHgWk","WfXMZmkEmEaexXqeJ71RMYh9qcM9gaFYuF","WSnVSAskgK3DQHc4bqMk5shNLijcGR9jzN","WRVqZ1CPhkaecMUBnD3XonSYHTyoEtMqVJ","WS4pAcubBGRNiM49QiQtRSk1zAUm6TgKFa"]}, -{"isUsed":false,"words":"panel risk address produce flat where dash hello bring debris brass unhappy congress van tell people sketch explain shed two mosquito barrel color shy","addresses":["WT3SAu1RsAjV7YF6zxDtaWPQc3ifiYX3Eu","WZBWqiQiD6kjMHH7WQs25483d2tSnP1zw3","WcBq9VC6PV98dKobZfaxV3Fvbp2dVaSzGA","WboYXEWenCUWwrtWvDM4hUxeGsKmkFLnUW","WWK3m6rynEhgcdUFxegCryDejSRuYdz9Gf","WVXTqVDmgzqhE3xR7WGmZAcx9gKmz15nF2","WQECjciLUPL5pfZqNEeASvKnPPjPNEVjUH","WZ4b6BHkoS7xr9J4D8dCwKUvUVvXJSGmpJ","WVYbNUVdMGp8f9ZcoUyFkejGo72vCT32Hx","Wg1vZuy7PAf4ZaJtPSKEKTc74qQA9faGtk","WYJgu7nw2wW8fXoyKaNb7AwWbg1YTpqGtC","WUPqETdxmUohBjizxgGf5P4iJEy8tn1oHH","WYeDcecqpE64uqvbcGFbRBZJjtCK979Ajd","WPPriEjbpsjJXg1rfcov8PxzTHdRUc9NnC","WYnpNEt7oxnrhXf7C3cncboD9orMGqMUnp","WSNMfnMoSY6rq6ztChccaMrKdFudRwsZJr","WcMHUaV2kZUSeMSTbCdrKjewBF6Lgnv2Th","WZVWrkBQQJpLDVP84BLcX3fzgYj1Skq6aM","WbEDgRg3vQnVrREeppsrzbxXTQhYELXGtX","Whg7vQMproM6Zqz8Doz2t4iYPTsTvC3siS","WV4QgaVXAmVHry8PSrgBHaWdsQTPQJc5bo","WgB5fycdVB7rBCZJh4FHWAbqng2xNsupqG"]}, -{"isUsed":false,"words":"art garage embrace target antenna wood sustain multiply season popular assume upgrade around foot settle word oval disorder come uphold obtain rough improve impulse","addresses":["WVicFS1vUAqJFt5eYvvrgmrc8fpLbgVk3C","Wb3qurEVJWHDZ4eeCEn6KCxFTTvA3FX3fG","WYo5zDB1FEM4Kz8hjct1qnXsaCNfHjuUk2","WTK65ucLMUuYYpiJUMKFNomzdKHXzucMfT","WkerJ3i7crEyyhKQqDZA51qfJZQ8YY5svD","Wiardi65DmnVkz4hm7LBBipF3EHh3TUatC","WfizoULVZrZLEtY2GYke17zX6pYP69TqaH","WkSTWSiBTv4sK15ML4tb2WLndCu6MjMSM2","WSy4Pv4FD4qMqRVuTManFfzpSXASbYMtmH","WeSgr1Rpvtg73UvgLi7QAAPECVz9WBfScM","Wj7asBreBh3dP4f4YZ5goE7gnkAhyqvfyy","WWBDDyqWHvZkcuXJ5NU1YsRPmUGa44R54D","WYkNJeoU6kKYiWgQZpBjR4AprUCDS3AoLo","Wjq7kM9oRa7BG4L9RSSzadEftQFikCAnXD","WmJmpvxyGyNdmQLPYkqMUuSZ2eFMfaxdXk","WmPEGNGRzUGT2haZipCVB1iGdvrywwhHKc","WRLryEioQn5AU66FD1EKC79Jb3iNtBNoKb","WUMsnm44SDEh4X2pS2hT6TVfMtNuzL38FA","WTbSxzN1LHBTNByvtzEjqicpeNxcGq3qV5","WjWSZuF6MtYrnftS1mncRmvfC677zLqNd9","WZHStHYAGK1FiFEcTZs9LVceUzbswhENcz","WXT6X3D1bYF5ATL6BXKvmfdmxPXeignDmg"]}, -{"isUsed":false,"words":"early comic radar thumb tent video symptom weasel three visual hope shed vessel else subject book dune top column search fork board entry chat","addresses":["WTiUcdEuVp2qgY9KNjHGn77Fgx9Q6NSawd","WhETKkJyTBw8m1smj1mo7jaPybjq1pVeuy","WYeqQFYehDF3iNbeC9BVtq7C9S5jsmiAUS","WXUYNo2PHGadGKvXb4J4mqjVPuyp9gNqo2","Wetx1XmmwYoJ3JQUnqKV3uyHFwDNC2d8ka","WkYPNeF3cGKguFXeb1PB9MiESSge3ZTbGq","WaHe2xiiKLN2AjkPPdsGUR2d6FofhYVJVd","Wdr3GkZxsdX6M8tiyEuJWJhUVTscF3Zu7p","Whs7cPz1vVbkfyCgi6Uarx7k2QdrQ2sUWF","WVyhH5xAmTaPCUjytnALpuid5DZDEnJm24","WdavSZLBy81gHQg4f5DhPetoGNGjBkDzxf","WZfoa5LSoo4tXykjwS6368ajcAv4TnYWbW","WbnVR1Y21UFy1WK9HEhqbbgfrDYya92ZAf","WaHcebVehAd7w61ji1EdsmG1Kzo8nNSZGG","WYKQPABMMhCdCTgAHqTp5BEQCSNKZgVAGa","WjHTWvpDNoPdXAiBG7nj24C7iZrbY7XXsE","WfWrDXbUAmu9wQ1J17NBs7kotVSBs3YefB","WgnxcbVh6KtbgyE5fFmhAY6iZdpQhKv7EG","WZgPonR4aZn4yJfmVWwyy2RGHAJY8FeMqd","WiDuGWP7L4nRrT39DYwL6TikPckdYVGrfo","WTCNBvP7VQxBc2iaqQyjcbfvp1SomF1DKD","WQj9BYKMMt21anRZqYJVqtUhuqU3SRg9X6"]}, -{"isUsed":false,"words":"gasp citizen true arm other play utility vault zero depart impulse attend rescue ability holiday tell cross lottery chief more pipe link very arch","addresses":["WVcQ9JstyXzjwWqrnV9X1aqn6vsJanV812","Wir3poGbh9QeaxzJiCchV3XLqyBwueridG","WYacMdDRLc2Aprz7fVP7DhNBvLdhFzzaxQ","WW5YAY9jCLz54uMYmaga3YW2hV5ZNspkre","WYDPn9zZTGNQiNj6fuaVquUJLgLVdqqNgZ","WcvNXEycrBLHgoaH1TLUCReBg4hpuHyvEJ","WffgdmXnECNT7PKnTdeTpnyGu6FQZJWM2g","WVQH9xn6gQrt5e5yXEZyc2jtQuysRQq6Sr","WYH8WMvjDA5BHhFheG1mVWTyg85YJTaGMz","WaLwczenjkjDDPvatDCGStPjM7xJ7UfimK","WgJ6UCX131yamRzbcyJ6D7SKMCqVP7Geoz","WRqxxtVBcxLeSQCgcBAKhVFq3Mxu9cRoVh","WSNFg4X7vkqYiuxCBwLxgSyHYpY33nUgLF","WWp3omUtkb8FNuFUKhZxgMGEEBCUZZvFXV","WZRB44RhP3M4754XBoTrdSAFepgm8FfqsY","WcL74djhAHPghSS2bd3YyJGwbSiDByPP6C","Wbuy7T4t4WhJPYUJ6hr4Re4xFnRMQLoP9F","WheSo7zrpHgeS834xJTMPWWoJRez7a3rB5","WPt9T549TX7rBiXJcTNxyvb5HPDU2CXHuY","Wi72hXzSQ3F4bMSuVWMqLj828DJUgxvu9Z","WTvfogsvjWxXVadQXUs7tKeARPv9B8J8WS","WaxRzBd5DyrtnuYKJ5KRnH8Z39muUakt7k"]}, -{"isUsed":false,"words":"sample normal chunk fitness couch collect fit relief crumble abstract ceiling valley umbrella reward pull switch faculty awkward trash detect six element size merge","addresses":["WhXnmjTk2xzUz9ZMC3Nbk2osCyFYFzdPv7","Wkja9P8FxC6JJsWRvSiMvxBYLTwxjMv2wD","WgnvDtXXG5Bwm25ovTws7taoRuEfnmm1tz","WdANu5JUgyqc9LRFPCabME25RppuZrgoL7","WYpzWhzLZ79e4r7xMyv4kyk4bMM4ncCRLV","WRGymxin7FDnKvJvAzzinJnLymy5GVRopP","WbSkjC3gRaPGnkvgwSyyR36q76scu1X52i","WmhTYrZkKCSg9decbLVqciwxPicicVcvfY","WUXJHTcaD4XBSW87yqBngV1zBR4gKxAarx","WjFMQtLStYeTKvsYuhmXu9QqTnZjfqvnnf","WRkonEHLo1qKAQ9q51G1wMNybc5zhYpisr","WTGXg5Z1ZTEkqpvUtGLW22uiLudRn1r8io","WQu1743fo3vV4SKAf9rc87syLgxGFxaEq5","WgM4Lb93DWrWpKAkuRicBDyCHPTKCSkHzb","WktxEWtkMnAL2jqymiR7onKq84bLS8pdmH","WUi7sXz4s4CsRkTwpYP6rGPBdzvvrHEQGs","WkcTti724uRzVXJPAaH7pZw3EaAQLETADG","Wdpf1Sr46Ssp8quzJtYsrxFDFEBEUKQVR2","WYDWCEWS4ddTBzF7W9vGDQe35k916orpVy","Wfo95FLimFqrG9XdCkbzfyPgYAkPEuwekn","WeHMScX6XoJvPNRKbNujAj98FtEttWrR93","WRXWFDFwQGU158uZGDaTaTxPMfX1eDBYtQ"]}, -{"isUsed":false,"words":"romance history recycle one cinnamon forest earth crew dance write defy this swap occur congress pizza vanish gun fury thrive organ panther sort fold","addresses":["WSE51zwRQAZk1YibswK5enwLYSGuXgrLjL","WVhxBXWnfXyXguRqdCPnUxup9WNauWWiJk","WTgZvPUBjaM5erJPyrDM4MeqDTU9dc6YpA","Wf3XpY66TJ1MGLTj36P2ZqoKhUVJ3UwRtE","WfGzZ4TnjNJHc2cR4hxpr4qGZ3Bff2Mrgt","Wao6eEEm7crsnY1K3kkePyUbp3sevdLJY2","WiTTuUhu28FH4CyeUc5hnUpDZi4iwB4iA7","WjcSQRbp2yKCbWmtu11mMixscWufVbqpFc","WZ1oLVLjoz2y1V87bi5JuXmKn32BdDxrLL","WkPJsKqpAnhPScEk1v23wjUKPib121WTy6","WZ5KqkoFEzUgDZTCFfoabjECX1MadMpHhv","WgjZvQt28VApUmQjmV4qbhvyxcxEF53VFY","WjiqnXwyxzrR9rZmmumXhHcq9AZ9GnvfSv","WXZZqzf37GmqirjcxSmYZ9JRT9g2wyJ1K3","WUfF6jG5NegKuPZ7zij3dqNAUqKYP9b65b","WNnHu43btGqA47Y93YeVDbheEgd71grRMb","WQRzix173CrpyXL96PdFbKjRYfgFKeCWRP","WVHXJnS462EtA3pvRmtUNRuqQK7ChE2nhJ","WbWbQQ5zaosAXMvvzoGjzAWn7Na22zbi1H","WTASE7X7ufcRtUUyjiept4DFadtrXVWEeB","WehsbDeFfx9Zjxv2cGiLkDbiTDBQb29NfR","WXo8sWUNBKFzJCwJs3EtJ4iiHTXWXemaun"]} -] +{"isUsed":false,"words":"waste tenant nation clay foster ensure parrot angle dentist insane surge wolf road pluck document enable expire famous denial walnut aware pond neglect kite","addresses":["WhW1cEBj3SW6UdgF98HaLNfJ5iPCAaGiq9","WhJjAHVCM8WCSJCYFBfZudhahgKuL25Tqs","Wkybn31VJSruRF4LBv2dzHLBMzgP99HQjj","WTtB51TixY3ZZpuHF2XXMGMWkxnAnZ7T4G","WdJRZ7M887AfJLRN6wgtXxw7uUTDNufSQA","WeXNF3BCAkp9gmpXMVT2kA5Bw426t7QSsm","WTwqwuFRfxzdNhTotwYnKb6UiLCGi23WK2","WbLMrwZVKYkH1fig77sRNvGTr1Kaw9qhtD","WkdfVxhP7ZusbzYQckEuMdFypgkQMaqMep","Wm9xrLCrcdnETVaWDaZyqwkYhjwgAzBC9X","WWsG3xkJC5n5hKwhnCtCMLN3wsoAiv8MKg","WVZjzbosfWU7syig5N4UANWapfKepPjkmJ","WiXd8YdrQcnr4KWsDSpGx3H5S8wBSanBjN","WR22GrVdUyznabLMDNyLGaXNnPEk5xUKhv","WgBhLnMGJ8rQKCJffCduPyXyZjTCvhE4oJ","WXmiBy2aZ6HKC5JCCoespc17Pwwo6ti9vc","WXVg1GXJ17nyWevwrLFVnHr2tuax66gn9E","WSH1c2tkkb2PaKjeSiZnd6bGUKghPX8qvc","Wg95f7fXjCymziZ9Tw2zwCtxQV1fiNecXF","WPgd34wu7dUMzQvxtL6SSuuZV4goF6Lh8R","WifcJYC18ZufGyhFR8y9FfEYUsDJnfJY7K","WmLFYoLuHgt2Eaw2gQoPZ5rHFxvKqpRuzf"]}, +{"isUsed":false,"words":"assume punch strong laundry pluck morning rally inject banana swallow useless average device spread small above insect melt winner insane gap remove retreat sort","addresses":["WWcgZocsPk3XcspLCYSjS8bwN7b69sqkLA","WctoRVeYu9T2k7npHt5q84WdtbAeHD6iHK","WRtzTD7nDvhTxvoDhfqPwvJWCcC5SHLSbh","WTD6SUXVKp2gDgSarLE8ameJCGkRmZKtHj","WgAxCupYmssMCFRDSAg74g3vG1reoQ34eN","WbD7WfUz9eeLeRXbLBm1tdGK7VifCRwcib","WgZQZX6W73SmB9GBCKwoDTH5LXeFyCGK6m","WPcE9riJo3i1E65RupGskMk38QTyASxf7o","WVHeg44MMT8xMK8wXsMKeYyKJC8bxjiaKy","WhuSiYEWZjFVpJR7b7HZiLrSAXaqP4rc2j","Wj8apz4pgqELShoYymWrmAJBgsaW1J784P","Wb7fU3atLF3A1xenEcMN8kjaA1bECbhCt3","WPa3RRPrKvzqgSKqBuQuStL3yoEuNV9rDc","Wm9frwKugNqLjJjAVVn5srFekmsPLBMULa","Wham461bSEPXihkWd1HRgFX7Jjrqd5JHBy","WZUmtngwdNoMHTGNpVaU8WDBpgdezA3rXV","WSkKZpPc7APThGVFUfyKMJXfupMmpvt1Fy","WZ3jCSJo2oeaHdMTbjp48yzsfMUoTnEeaG","Wm3QxDSCxbEdkk2V4PTCcXpA3sssynppeB","WazjNjhRn2HozNJ5YpqBavvyoNHonwZtat","WYN7Rvxx2puuDDGcxmmjWdsRvicgZ3ca1B","WgCfpbf2saGUBzQM9JBjuFLDSNZLGppg9U"]}, +{"isUsed":false,"words":"myself finger movie gauge rack earth ivory music stomach abandon motor bleak company grab sick focus viable female museum october world dice cross any","addresses":["WU6q7nCknr7juty7TtWMLsGL8ija5vT857","WQRhG8zBaGiaw5cKHLKFE4d8T5NhvDM9ai","Wa6kRrk661DyWyvYn9qoteZGFPWUnxhW2K","WS19RrMmJM4eNEX8LNhHuAx1YHmswxHPaw","WQ24Ts48idvMxvWJS9c28xSBhC8VLrZAd4","WZFLWJV5JwbE5QAuEfXHMEVXofPxady3Un","WcJ9WRoyoSQ8K3D99tzhrNSWyqsv7gmD1m","WSi8YrpM4q9HWA4ogtR9adDDSu5Ube8vJd","WaexFDx5vXv48ej47tpB8tbc6ok13WpCxi","WeoVsjJHAjRixYTYNjL47ncN8qbR4gz38V","WPuRxSqGGkPfozEUtZRTNjjj5BAkkGN7kh","WXr5Kf6NViygiR3yWTMajCWTW34LmZXkXf","WmWwt7Udr4rz7sqQbYitPLWPM5P9XBXwDe","Wk12N86PcWccbBTYSoaHFDL4jN4hMU4nvi","Wd6o4uE5g6Eti63X1BXAzHXsJjsbRQAogr","WPRZbqXuP9NYi1ALTiaqzBGLPdnDCQmeTs","WdxT2UTFmpANAxjoAgFnueH2qFrisjrAJV","WZ2MEz5peQNo7xH3xyb3KX5RVWXUV7AvV7","WYswxCfevhT1KjsujA7RDANR9yDidRwzqV","WkruzPjX3D2t8M2xPf7N9V4g57bA4u5Ehg","WQSaKj6pjHdaPwgqhSXyu3JgJWe828xYZ9","Wbd8CpWy2oJpPHcxAQfnMojEt4Bw5cRsoP"]}, +{"isUsed":false,"words":"vintage dune moon crucial chest pear dragon wide miss train weasel opera reform card top slush glue gorilla family mix resemble circle deputy cat","addresses":["WeCLKCD5Do9LzACVGJmn4rWozmfhY2XyJA","WQUpw9HyspbttcuZ1wn2u3gqe6pRAs4hfV","WXj63QhUtBJjLqPC8fjbGX2YDYCwWmRsSE","WhtCKtZQyr5Sh6cz8zs5bqQZ2PXXC6wPSr","WigRVYYywpe4zr9H7YmciG11KfrigVNQM2","Whx6BKThnXRGiLYRY1dwDgEWDqLZvRaGRC","WWAEMWuE7eig7jjbcLyVtQNzC5ZryXSzv2","WQLrcKFfjGnqXBZ7v5ujX6wHjML5MF42UM","WZkvHgP8eYzTj6H6vsuas4AkF7pSPZUFF4","WVb9hEgXBqgZuxDP9kraDeWcsMZd82KsLz","WisZnMrbPurRgmPHcCcWJDQ1RnvnbMViAc","WYu6AK9BPZ7URNjEWMeVmjedaSaNiZqk5A","WQ3jCEfYv3U9NTj3BQBjNhifDpcd64VWST","WRGgAAbBKUNUVDPimH4MbXkRQopiZxdhXE","WPy4hAZ5uvnNBFTuEHtXn4xgsNZJC8VtU4","Wkku9Ms7H8Vfp2QfNWCayBwk6mCSxQqUJp","WjuxE7N7ZVMZYikwwzxmTYgcHfSiASdUJT","WjXVYZFNTJB8ArgtZxFmTCwcxNSuijvmjv","Wcm6QgPnkK19tfZs8ai6FYwMbjXDYWu8yY","Wf4MBsVReW63WTgnQwVAAiMdCzcQszMNwT","WgvktPvAaUD3fBNcyhVjnzG4xPsHMyWTNZ","Wd8cngLa5croSeL6FJtmc5AnpjGjSr8bLw"]}, +{"isUsed":false,"words":"draft devote gentle lazy claim visa town you wasp enable close town copy exotic opinion village pair target later tell gasp cushion busy fat","addresses":["WdSFvB5xgFHDkPmPadWe3pXTAocrNab8ff","WXqKrohMMxpoqj6nyLtN4MtdWG9GhoL1kJ","WgPAfZNSX1TCKP6PZtgDs9FLxXaVmGexVp","WU1Zf68Q7QSatEvKWLXJsXUDyTB4RHnyyv","Wek4XjhnQM6xnAqE8bT4fqBL6RDzTdAwVU","WheGXdcVrpPMvhJvpV4jXN9twPYDsCNRR5","WemF1ngY7b4WJrtBVvVyAynEHjuQXDXWC6","WPueVMiXSqrcKkgJRvNUygN1e2gpDUA94P","Wd2GXYirGxVDZNgWQXgkH73uCh36Zy2SWp","Wc17TLc4Ww19bENq4s6KE1ZSkj3SrrgQiX","WhTdFwrDHLWPeeFjjN39a9H7ncJDHno57n","Who1oFCMDPUo8Zi5SfYQ3zXAdyDJxps4Zf","Wm7FU2S4c7j5YGmRUivjuEYZhSAoiiF1gU","WXK6cykxY3UeDq359VjAjDkFYMSSqyevxt","WUE2taxprhttAQz9cUiYL7iZbKKpV4iaif","WkXzNthBCMxPN25BxLhzK3bx3qCD9ggt1Z","Who4nthXK4MKGzvEiNufHjAFudERuJbHqS","WSXFFUpp8kBHWbokpgc9USQNwCrTTmBB8S","WhT85jYTj8MYg5W5WdveL5qEFi7mRyUp2d","WRfe2qF29Z2XpTjmUyS4SJ7T3SeV1Srkf5","WQZ1797yKqDe6x87eu2UWva2qxqGT6DF5a","WTTWkEcUYw6bMzyDYS5ayYy6zTeaaWNKK1"]}, +{"isUsed":false,"words":"myth tomato little abuse caution squirrel input tenant region chuckle permit borrow domain convince rebuild suspect express giggle rain glimpse paper tenant rude sunny","addresses":["Wch6u9P1sUEHUinfmj3kMSep4KZz7N5fmD","WUZXf8i11FpaZobFJvWYThKrFvVLg7qj7g","WfkeHk9b2JL4WC8QpXbZM6cAmkxtF4Vert","WigKHTWnMHx3YsDqfirzeFi13gGCDpZEbx","WeT5qEPppeP5MnTAeXb7rcjadVonw9UQe9","WUwigbejxn4rK5hddwzQXjwTg337jenbPA","Wcr6pmj1A25hBbdydCMvgJ5sXvkrvnSskA","WdWHaKr1ztN92YqVwXuzy3uCTFVmrtRHiJ","WfD3gjXtSn662juFS2EMnhmT9UGXLEhik6","WkUdQkmEPK5UobRBMYQQKYwFAempfdgRMS","WRvcvY4eobw7Z3943PTKajqH4fjizkifg9","WWX72K1x6BRpSaAkfioRPdZioduWG6pu62","WmMwqFWQnTTaCCWQD41DKQ95UNhHN6CNpC","WWatV1Enz4qdoaPbhy5t6Stqd2pzMkorgU","WiLGGyhYzSEKFATkxmRvBCcC42aSdPUoKE","WewX8HoaP8nVunH6ugUTTfppK768kaRneg","WWhQUMS3fFsGVvwK9Adkyb4uzvHn6betYY","WadH6BpH3uTrNBNjpeZ8pmHoX2j425KVCF","Wg8mZkhGCMq7xfRWe2WKFYKvLesKu9pMzw","WbDdnJVjFC1EQbHdRrtDurE5SNqfiVUUdn","WcDGCJoz3qT24J2KL37GpF2PeksKnMJ5t2","WbwuVWy2r5PvynYjJxrVJ1rCoCjpVkDzd9"]}, +{"isUsed":false,"words":"swarm student behave mutual switch mirror select butter reject chef wasp blouse jealous ball glide slam pave dash glide delay senior focus uncover day","addresses":["WdkGrCLGhnskCsWLPPQm2AanDmZe9FtLiF","Wivp1ZzcRpiuNA2cfrFAn1bi66h1XNBGQG","Wkf4pMZ5Tp8yqACtUpx6syYpR9BtVM1VM2","WPJTSjzmDv8fqp6Ybx7Gt1TTv8eNTWBTre","WXHE7zAYkdzy5qKPMW8hafLJ8kSZLqBwL3","WdKPLm1UHs9rDwqtATZci1tnapGBnnMCqK","Wgjvg7Kv85sGKaLmmSNo3eoYxAnHpLLhwo","WUb3XyTxofduZS1wbx9aTcyjEVnBoxMYnm","WX1NSonaYXciJ86DW7auSz4RDFFp3gjjLW","WfzLf61jSS17BNe7qyj2YKmY8vF7kaL2GH","WcAjfbmihBe4YzJ3UuCDTVdFwNihNvaDvg","WRNMN73SWBwZkcD8LCcjVXgCa2AB2SQmG8","WiWPWi5bzp5YgN3MPk5mGyqGjHrJHNVAP9","WPJ1YZcDuEYu4wtzSVXkLgLtC663vQz1rH","WaDupYqvgnVdouDaRkYkCqwkspeK4wpJW6","Wc2gm8zekQsGAyFDn1zstELsYk8G9qhtTT","WW4usUdVqBZ2fqZhoL365afNeYYpMrGzMY","WQS5hwAqz92bKfQcCtNYNxjZZpiYefqnRn","WPX2LRH8ru1MVMqzvNrXfHms98M3FWbLUp","WUVosgDR3TJPbqMzYQPPcpY7wUsuJ8EqoJ","Wc22rVBwmue1dvxrCKFHwYvjpHjm7357nN","WdhmFbrjrgL6GxVDumtbVuThEB2e4WnnPz"]}, +{"isUsed":false,"words":"bid elevator purpose because reform trust exercise diesel frog whip frozen donkey rigid peasant exist despair talk when mom liar weekend giraffe canvas tackle","addresses":["WPxHn5C3e1jxhncbrHCi5Vx5CXjsqtryqL","WdGDcDSx88QsdeEAJmRSACgBX2FKqSjPvB","WjDhpkPVD82izzZUmavqpJBXghX9uPaCuD","Wh96HaQMJWsG4aQ6iWZP6z4xXYWihH5tdo","WdiFC9BkCKtfEM5DcBAEfyqGuc1Ca3JL8w","Wi5cwT2szDjpwx1NpKpGpRmBrigkkC4bg6","WdRYkWAwjW7jxJkXwTzsEvZuPP6X2Nk6vg","WhFNiRPns6qYxMSrW8wPSMGMyPXhPw7hSs","Wb9GxnH9cgcHYq1MeynqYfBzBXypEw814Y","WdhT6XstJurYUqcmJzFuDPVj95wmXq63jJ","Wfn77m8RunBgw1hbBe7NfEHF3fP8xGdiJG","WZtpybLGVqB9wuWm4gnMwA5EneprsQrc71","WZrmruPwWia3y2rqEBjaQMT98Djjt5LyDz","WSuWXkScX3yez8xsj29VVQ35Z4PdXNWfQ7","WeKdGq7bq1zhCgsjgBY94fXW7fN7jov28X","WRBizvcqDaYFZWpmtE414htiiEKC8kG4Mc","WaMuHhBCzcPNkW6iqyCeqBJAg9aez1eGJn","WSfiX2BthWCkCDFjyjqZR8yH9zEiejR5mG","WU8KbkWvFwuUHp5H1hjQfyRfhQk4yjpa16","WPyFefidKtJxn5PQPiaL8qrXMbb5mcZbJ4","WTQBMo2CTKDxSrMHpKy98MwoSyYA9ojgin","WXcJaHSQyCTVTiDRQX5h9y12PqwGXdvfTz"]}, +{"isUsed":false,"words":"result gasp focus coffee accident analyst shuffle wild learn govern artefact window science resource claw cherry plastic narrow letter system office slogan cluster hobby","addresses":["WV4Dtu4riybfMPV9z4fM5ESu7ANZ1G5s7F","WkF5SXFHpMbD7fdGNzaojDFoeyMVJa1gxi","WUYaQLdCU6DT132xKB6Ui76tjTctBDTjMW","WdKsVAABWxanSF5NhLp9BnbfyKowQv6NPn","WaQvunYFD9biqtxpv5BCHhy9bRTnXVXaUj","WPpBeaUT3opVwNACopCVfYByD78TyZaDyd","Wg1U8eokUYURP93U4pm1gAkBir8J7RijHE","Wmyiv9s3ppzh5c3E33ruiTPw8L2iNKcoRS","WWZqwc9V5dB1gAhWsqbRZJvAP1r5EZbXnA","Wh5DpmLLUxPkyisG13LQZq9pEM66QG2qVJ","WP65drQax42j4vovrAgkWUpa8JpqoMjZh7","WbQKh6zmdi5gaAr4Qa1wR8zaMLLXMo4DQp","WQJkfFJTdFcsHH8RAYMJgbw4VywpPfvDdu","WP91hMGoVpJW8jj19sTTA17MiXua3RQ2Xz","Wc7nuKRA1QPGLTym5i9d8cNktFoA8NKERS","WkPD9AgaDd1KdU4rynemK64hmSrCXiCfqg","Wf8ornaPdYuzJVaGWaxE8pXPHL9b6k7sQc","WcrFAgAtiftrZPnpgzqpgVgYP1jmbro16R","WWehV2dRGX5WeBKcVnc1nf7QocxJ8injak","WmryUaRE3eA9iHMCTk9pExPFBRJ8ogEkP2","WhJSLnQhidy7Myx5UBhHsXkAPofVZTKgmM","WjMN4vRJntphWjtQnZTRxkDBBaAMhXyKkx"]}, +{"isUsed":false,"words":"boil suffer sample siren quantum rare matter tuition debris scrap remove tool excess owner unhappy slim sea paddle upon review fatal sing tooth squirrel","addresses":["We3BxmgogCGcsnhTs8VQvfBVzyPStL1WKu","WS1r6JWfymQCmo34TYdKWceuSXbpmb7kiR","WkRRgK7bLtppg249W3nPfMXRPCZAjPKFWi","WYoyuDujnX6vLTJV4fAq4iZLL3KtUNYXx7","WTjmALwv5Ahpthz8X6bUZsJcvoSKKbbN7P","We27ccPv3p9mpgxWRxeqKz3V2eLUA7MGQm","WcMWe68ar4xV8WuGf83cP6BXzw45UKtm3R","WgujAuxaz9Z2t34PWwY5yi7Xr1EYRqRrYD","Wak954sWgCPgVKxG6P2Grujdz3uyMKeCdp","WfstRYSNssatmu2kEdg7mdAVRcxRZaYZVp","WNstkLtA8tKZjZSXVzXtywJ2Zhaqj14HkU","WbWVF6iwfCmoytCiF87GHepkmHX37ZATg2","WZdzTm9rP3bGReWMTwUkPEzDChzcY4nHr9","WhwVvs2okWHWumceEpaMfieb2qYY2CYCtt","WZyJ6cgtwSisbe7hioMM8Q9aCnybUjoQtA","WmF7HsPjfzvvnhK8Vs7xaSbdRvKSroV26J","WTyudipFToa6wEoGfcMsPeGcLpNmugLnyV","WdDCSG2L1BkbpsN2aFW6pbpfHGASRYWqDh","WmHmGyEEB5vvpm65PzF2rkf1iGfTWFcpoq","WWGabvpjYi5c92eiDLjCngzsFpRQVe2mF9","WPvujrxcZGAzFBirGn2obZxEmZwxD3BB7y","WceBe245zq9QiHdR81rk3bSTypEeosF6D8"]}, +{"isUsed":false,"words":"cheese moral list small tide surprise sausage dumb estate suit spare arrange open lecture soon enroll disease happy crystal resist lobster artwork parade client","addresses":["WVbmdb12kgD73FmgFGSEBbuum9duMo9TzA","WQHGsBp1wKeTiKvEKt15VmRWXJnm4D1S3A","WYn5kbZVSxFmNDSNgaUWvziPMFKCYzYZNS","WR9GrnSB3wTjW6DxMQkMYAuxrDfxtPbz4N","WSyNENCz8zpXFcHQm5VBjQj9ivaYZGLSoq","WS6EDZp378buUimeRD7j7L1wGH6AYkg2zT","WZdr6CUHopu4yvs7wxmLsZhRtR24yU4m6c","WQUkza3ofAzRU4fieFZYaFbSmoFVGjuxni","WYx5AwqL6WtPMSjtrLcsHdR8WbrgCAzskP","WP1i4QbRfSpC8h4od3LQA8iBtVvyRkns9C","Wmq7xbEYAUvUdYTjctLp8qjyn6QjiC9ePp","Wcf3Yobdotvozqhs4SfDo1chqxVtyTRqZz","WRX16MqKk38mR7H967WWXDzGmfYfmRfqyF","WbHjW1sE4KmjGcYA5R1KKeB6DT5g1mUB9q","WZ14sGZx9MB3WYNJxbzjxUt9kRTAC1UFbb","WNoUoDwvuqDahRRb6Tn8k6Pv2VNFEaMifH","Wmww7dbcPnwgCcJDYQVcQgnRchNWD7GkG4","WPtvvb864yyuV9UiV1e6DRJWLtPdpU9Zp7","WWchVuR9TpDRieoVwu1R69JWeSgzauRRsW","WTeAPsJ7LUbYVxTsgd2MUvjQNFnmCxRcsv","WkrFuergJk4cHS2ATziNWQZDGRg4b2Fbtr","WYZNq7fLt5Pvkte5bntsBs8JkNibJH7og6"]}, +{"isUsed":false,"words":"minute never spawn various fence rebel come tell repeat deny rebuild traffic ticket patient near guess mother noble soon picture health glance boil bean","addresses":["WTaKiPvFR8AS2SDfat9kwR2aYg7Rt8LYvu","Wb7Xr3ZUhoddmJNMd7kzmxqTKHwLAGUBXV","WZUwZrMzDsqp4V8sKzaBArGYWGRBKK34gT","WeBKFBAgqSfyQ8E5yydNPLmNDW2hk4Yu1o","WmDPdvYtNFffsa2NvTbGXQ4hBamDe6n66u","WjDUDhsBe5NsJ1X4yaSwsV5aV5AdmkJU8w","WZbSP7EBUXszjxsH8k1b7Kzi1fFXSyKRWn","WSEvtujqFka5KrtGtD5hazRvv3eAK7M8a5","WZELK2GmmsSpw58eVmJds51ptVhzLmgs5n","WZYZJBAaLyHy1wgqSnV33PtCWakHNDsDhZ","WPFvAqbwxvVSNNWUzw1vVWEUj73wPjk2t4","WPuhdM5ZyUnaFcQgxWyXLDkWZ48kFf5u3H","WYNwWeGzgpA4TQ9BTtKqwQX7Q2ERyfwyDf","WUeKJub7kRoFzannojdBmJK8k9bXExRUve","Wbgfjc2qVeUqxQtwEggkh2uy5cNjQL9yBG","WRHuc7gTpTyUHxNSywRZDDRv6T5n2PnjNJ","WUEKixoxMW65NkEfAuTCq4cMXRGTLfraif","WSurpZwkpWXWsB2fLDWxw53LwRVTieNu6C","WUVVRfjXyTqY4G92UV3AwnZVda7qW76ZJP","WUqM47SZxK5pYLQyqmZ3m9bfysr645kx5U","WTPUGYHrBxEJFsu2MX8CwckdJVU1hwVeq3","WRzjeGyrj3URu4LzDSKdGBzo1S6PtFwbFU"]}, +{"isUsed":false,"words":"desk sadness video chair clown thrive begin muffin cream wait surge gaze state soap off bird inform filter alert year chef galaxy fiscal scorpion","addresses":["WWfKPVGq4JpQLuHnmH3drM359ZJ2ZzcD9n","WfFvGhkVKDNWQx4LuwLHsUDNSyiQWA35wB","WWRS8xdK6KkHNynDBRfm6eCEFWH7Qo1uuw","WkqCk1UbQ3HWFL8PhvH5V9NCffU5aKri3h","Weg31UqNp8h6uFbXhoHxZKqQawQYEdNe9t","Wg12C3PJZPYKcHz3HndnfytdddE7NPGq9D","Wb5i4ACZqyYC9PcKCuGFrP9TetdQxoY4nP","WSP3tuXmNPb7HgcRCPiji7Sgr3sULRYnBq","WPKFsF2PAiguzbrctye5CXS5hDay2vPxg7","WeoL1bpThxJz8u6Km4cbFHR7UQjv9FashE","WY3cZFZjMpDr4XDJ2DutRy4c7MV9AXq1dc","WPfsYeaDf8mRFPWJsHMSYiUN4mAGLrR2Ld","WcXcep5JbVnNS7nfmwYuqp26RrgCwc6scw","Wa9bwVZCubHnjJuw5JxrKri912QjsmsEoE","WW1FPbeMthXh6Fk6yiGtBb9jCwquC2h4kK","WQPF1u6qbomTF82VFjj5P6AQZmCfMGLeWL","WeSqGE24aiUFFmQdAWoJMbADN74uDKErza","WTzP9mbrLVr8wSRo5HgHZ22FDzCLUxJycj","WUY9Q7tqoUwbn4xEWp1VTTGxX2LRqPkWD6","WW7TvKmftRMmpa71izFY4ezv39GSeKbXMQ","WiLnP9JTukSRvbedyDSufYc8sQcpXAibnw","WYPMpbbZFtqrNvZWKVBETosPw2EiMoi96N"]}, +{"isUsed":false,"words":"toy clarify gospel keep strategy deny fee legal practice clap scan disagree snack rival bag review submit worry balcony first party lock blanket phrase","addresses":["WaoXL8rckTRDuFWgCShrqEGvra3N1TnbVH","WZpgz67pNXoSPozUq98gfh7uyxgg9eVfi3","WbadiunCQrEcW7vwgPLc3oJSuzFNwRWcqG","WXwrvU4F9ASnFBvwebPuLie9wDQbT7UZG4","WQTmHYgwgFRFGdh4TWrHdpRxo2X15hmQ3P","WaUFKVs7b1CvpU4YAVCsjN3KnL56r8a2Nm","WUcNNqGpEdZf2sr52dHDEL8QNgCJ29i7om","Wg76vGsWrAETXNSXBez6TAV2ERcWxoLB2D","WVrPQCZQJ8sfPeT5o5kV8FAGdYG2gDyFXm","WmVs81uSRTRz1VD7pVPnv6SRiYdHLEb5Gb","WRrLA52BQkCj87LW6Mi67Zps6ESG8Hz53j","WNoX1HbkCYVF73YyR7Yyzgd2XinfAbeffx","WaoXZoKhFiWEBdSnqSr7hDJ7FvbAuVzZs5","WcnP8v3VQzsHk1ayCQPetuHi9sLC2Dh5xU","WWtfDhY7sZmBFxnY4TEU4rTJZZLMygZRaw","WeQ5baAyyqikSnfQoC9FgXZD43n9HUcPbU","WYtjhQ5ir28XgZoxmTsQtwJqMrxUGRXxZa","WeoKbNwxg8DE6Ebhvxxs88F5t7oSg1bfhf","WSQFkpssLBVDiB5em3RE1NU5obky1udPRx","WYsWHat4FAapgmQNXuhFLHkZ47sZjDmzsS","WRMbcj74RDxjke22a3eeCiFXMXKHEYvSjD","WmZCUCjeusxyk1K5NzcotBCqHHn4CzZaoY"]}, +{"isUsed":false,"words":"little census rice banana ozone clump phrase legal trash gun wood island palace cruise beyond perfect endless list pluck upgrade improve submit maze float","addresses":["WgweYLTBhQmnkv27NNfrppjxWMVjEUG72N","WUQRchajBitZPZhn3RaYUtJ9FJ6pkH7Lbo","WQzW1xLkZBEaJQXeMtAXj9Kr39Ff3K6sip","WdN4LM4WqMR1efiXowQfWRYQHSPoH9yvmF","WiFwnDqGVse8AVGozqJy3JPWRyQLDzbRwQ","WZuQD4KGSUsKi5tzZPM8GC9ck9wBr5w1Zh","WfpoR1hthZY3AozHB5Mwh4tEFpAomVLJ1q","WkApF3aKTKnCNVvP4LJGjjdBXUFWYc2Yru","WUPTJ9enpXuSn5WsfX9ratG4153QkXXFtS","WYexGCni2PFLm3Wx1tn6vfohYEmihB8gdE","WbaQUzcHfQaw1j4N96BrJtPNq6UrFCdsN7","WiZ8X6jK2Nt9MD5GjAL1KAPC2r5pjWJdFD","WQajq47YkkEGcZrzwgpjSNzCePckazHNZy","WffGRKkvdANQw4BMcGbo3HZvw2YChjXnPx","WZRTeFC581MKrpUkXfHQKprEa19ggWbxMT","WPD1QpmC2epEVLyGjCwjCbq9mFqYnKy9Hz","WXZs2CNCU4WnCbjLRt6JUJXJRmG2cj6ynE","WjZvM478EtrScuu8WwgGbiNEEBJkCnLZMi","WadaHvuAfGAKp3vN9U5W1Do3rNxDCpQ2jb","WbD7JXiSvpohJEjbGxeKZB4FXF5JPWp4ci","WgidjJxLB8a87G6uKgRkfn78FpHHcv9dzj","WWsWxgZsXDPNsBdk72qDCkuWu9hGm6B8UQ"]}, +{"isUsed":false,"words":"apology slide mechanic era announce wolf sauce mixture village jealous leader tube churn below define breeze teach pupil gravity salt oak time keep begin","addresses":["WRnzUmUtPBzyEKR6YD3AVS5ZUY9wJ9qLM6","WV9nfrAdGJyYgrz5VdEnTivReWFN2skq13","WenPntwFqpDzVUEazyyJUS8JrdZeURAYL7","WYcpjgVQGvNwGccQyTxYoDRT9mbeMCDfwj","WdsmGR4u4hP7W3ZCaYZQVtwNB7Lt6uhEVy","WfTmHmFwMTRc4CEsYZT2gETYbzsVywLasE","WdHx8MEL7c65m5G6mff9WN8BZfN63YeT6g","WRWVe3uVwnSbfkwAJdRBqLP3HiDE1DZX5G","WiYTtUAC8oUv5rwv1e9rp12vowENGX7Rm1","WVeXwTHzDcnK8Sdm54xxgbtMhAktuRLM5i","WhFSfnY2UijkyGfuAzj3U6b4AAPP9HsmfG","WQjADxqN8xWiWWVVYKWwKcsGG5eQyTFujo","WhGctcbM5YpA3KwB41PyXQdJ6xV5ajQJc1","WR3L7b53WW7ptVe9LxbRoLNKMwqY6zs7va","WgSAZACucCbDNvZuDzqcQEvgyzbvZMEPHG","WWGop7EWDxZZ8Kep6UqohyRPuABybo11FQ","WbX1429q9Zv2uFEvdLjAYdDT7Z2AjdZTKW","WiyWQFFcsBHCdABWQXLwiWjqgA5qQ67MHc","Wf9Pyz22nGdsPJS1vR1qRSD5TEhsUtjMnz","Wfg2BXXG9JwWy6VxrUiAXcdmotToSS4s6w","Wfs1gqv9wfYktvowTHGNCqrXrALqcPCVRH","WQACAP7c9ZuNEJchEkDV8DRacsD7tmFZUF"]}, +{"isUsed":false,"words":"sell table young unlock thing trial shaft picnic slender helmet flee table kingdom fame census home camp gesture project benefit state tongue bar cart","addresses":["WXnpUpEwcK3Q1az9ccgg6zSG5JHJd16SUp","WhXQCa35xeCvZzWJjQU4SMUXtUfTvZhggU","WPTZNLMuipecdPNbYbJydQnJqHrbSDHfYj","WgkRTEXjbSUzoBRfSSoptz1Ka593PCV2EM","WWaJ7DMZKdiAEBykXEQFTjQZnqJQ7h8b9E","WYHPxAFH9LSU4NbvVt9Gy3HaCiQ5hjWn5m","Weu1CZffGAC5NYqYnX8X9VAXSXCyuoUUom","Wfg5viAEksM3p1FxbhA2msLXZPuZMHB4PE","WaU5dtZ5zCPXD5yrKmeX2Zc7qvjySqDqFu","WdppeW9wzfDkKXocc6MmBbp36aLikUMnq7","WTybdV2ZxejWgffo7Uh9fFmjtcEL4nkoXH","WdMZay3LN8GNABMh78Qkz7uvfcqdbFLkmp","WgMQoLvwRgVJs6aGPug3TsV1PihfsKkSX7","WVLcWyQHxFM62D92yJCrJpRzwgd1t6Zw9v","WhdJLqWbHcLDwgCriha5fnGWYdBDr2PFdK","Wea2a5389rWLFVujZxC1khgD5TwnQrotH8","WitqGaefye55GypxfBVZ6TUg4sXRNJwpN1","WgWKYmBVFWbwJCRp6s1En8SpRAUn3x5dbe","WmtqDRJHUhwBS3YoVwo6QeWbD3qAN7L62D","WaS6Kxg2SBJhMYgY7t9ik3TGE4w5jjjUt1","WUZGVUZ4B5uvF84BBD1zehidqokqWwjsJe","WQoyXKp1Fd8LKVScHcC4ovucr3Pyq5bAwd"]}, +{"isUsed":false,"words":"menu flip theme finger other sorry harbor tomato blanket move warm swamp metal tonight lift truck income peanut sword brown upper use reveal combine","addresses":["WWgahoGeksYQE49BfQGwzmVA8YtSTQjwgB","WeShYaC7FTo52YyBMgYaRzjMvBLPag1FfT","WcFrFjGdRm4V2NNgMdWNAvcU4pQWbLdYoi","WkCr8CQswZbQQnrUjPnV4AMqhtsLDV11S8","WZtUFNzh6TZkv1eyhhFt6SaYnQGDNsd5nS","WfKMmv44msKqbk3H7Y3ax7ZqCm7Q1uZfPb","WWyAXvBPGPjidTuy9TfqAUoyY4cyYcqPKh","WUokbqPRZLJdno9gqNJonoumaZvLXuWvDq","WQ6pLCWoLsE8CeJuh6yenqtvjm2ccxPgRS","WhPws4YswrnCT1ry8UJrv4BrkZ6MxA5Eo1","WSwZ4ntV9LSQnwSCcNoBidL5xRKxFMqrvD","WVauQ9SZLcBUA2dRPUS5Xj9rSbznvbhMFV","WTiubBa3kqytcMKEGYHvcR9wNy94HNG8vN","WmSSKC4GGje6g2bhXeaCn9CwQ1bbsLQcw2","WUiFxa7Cq2G9SahEk97x7pYrPZPyX2oRJn","Wd6jXcAjAxVnCBctGcWNpt1EqpJpHNxrct","WZUHqY9wbr5F67izF262A5C6kyue11ngoi","WaT8mwAxeALmBaXekaJa8HVui6i7D8Xyrx","WmA9AWPspXYYfYe6L3u4LjcsfBtf2bzkJX","WT4yLEEbvxqpYumv4YuXPn3xM2hWSGub8h","WjCgEFkeL89CK5SSpuJEiVVpMiGeo1cM9F","Whyt3NVTuFixGvoFFokE9oidD1BN5iTR2Y"]}, +{"isUsed":false,"words":"cricket enhance drink negative unfold prepare dynamic anger garbage stock label betray duty flock write cargo cricket awkward use labor picnic giant must monster","addresses":["WU8QfbVdtesjYm77mzdQP8RtDa8YQZty9C","WQXvGgiED56Ntiec4ucKGAceHTXjXB3doW","WbqVg6sRsvo2JTy721gQBHm97h7WkQpvQf","WfW9Ntc5pWFRWQa1PjnPH1g6dqBADtFpYb","Wm6K8t8V2C8VfkJFdR6cqWKzJvzqU8QP8g","WV2uEy7ueFyi5FqSZkMyJJwTsmgaW7gsdx","WZChkxkRYy7uM54g3PAAUvHdRC2CR2LPmW","WajPJK37w8M2Lv1fCptzCSsQGkkWrTiqMp","WmP9pXLp9upDSVYuDe47c659vdXQRDcuyG","WafrASDxei8bo8UTNkWccDqQ88NrdEqSWp","WNzmLeKPPnZbxqrax8ywYZYKc4m4Lztuvi","WZwKbCS399PXu5g8HAyQ6EYjPDfVEgCTC1","WUoLGMykxcNiGHhuEwPUm5aXQBZFdSG87c","WdypY1686tp7vPnro3kr9UsdKc14UPkhWg","WdUW1K8aWRvMfVRf3bekuHCf7QSpcv6aAE","WWpmwtu93YS4XP3P3tfghbgKRfg333grxf","WYy4e5poYo4CXPMA7GuiF9YGets9veiAc4","WeRxeeM18vAvyvkqntMbLoVTErBKYCJwA5","WUdUTVqZvoPPyJEVHanCCRc1XHhCdZeZLA","WTuJ5CKVTEp9Cba4wYBBYhAHfbe2oCMmk6","WWTrjAMxWifG5V5ZDYU8U4CFbbmFzqcvzM","WXgb4wuSBgqhKqVqHo5ERwKaWezrJqPQxT"]}, +{"isUsed":false,"words":"destroy still empty illegal phone midnight maple state topic promote feel survey riot point ignore sun trip can venue elite consider robot host cricket","addresses":["WTUzzBDUaxRKGtyG57Q7Ue7VWwagWTGt9d","WfRBMhgP527jfdnp25JfEzBt4EVjUUcHaD","WYPdU8BgMMwtZqtPpeVKDFGHUT5oE9uNTN","WV8wzHFYmWxKb9MAVp5NccgyJHXcWFPY3F","WYWmUobQbWfE38NPRU6qC8YQMNuGcGhc2Q","WdFMwBN8iPBDQX17qxXPTW3epj48uvgHih","Wd9aSNrDwHBPeene1PX6saX4UGPi18kpCA","WPtvRL7HthFggbJMsmFaqqa87ugLeHXQKt","Wh4xTiyK5hvkMoRwumuLioWSdFxGah3zgH","WSsWzJjsmXzo4d1oq7xfH1gv2EbF3SzEbE","WeH7BRPHPPsoFZmSMY6GjaAN4KrkyzDbGi","Wfg42x95Qc3AAfZGhqLQ47UzWkWSPrsroM","Wm8Ez5jbgsHTuutPGwTGLuprgHN9XNWnEq","WPAsxnvrdtQokKjfxGUyEht8VbAmdXLfe1","WmFf3DBM9xofe3XGWKhSX9nMTpw5JvTNfN","WmtXM6nEsmhTGA5pJHGKAzfjtecGtf57km","WNrVTfTAPNAnGYaExf7vv9KwhsZ5SivSVm","Wc3Mk1jsnYL38qUVqESb8bis1nTgpeTW1s","WjuYqqVLaWRG28godCFXWCEGXRMPdKuoLf","WfHspny2A83PG1ghTiQQss8XysVPsa3J13","WUJ7HzDezugRZhkeqRnNVzJf6jL1SfLGa9","WaZ3EM5x6eMS6vECzsgJy9wTYJDgfQJBSE"]}, +{"isUsed":false,"words":"dust taxi size detect print sun across budget stone find exhaust assault position labor immune prevent walnut target minimum catch couch begin object senior","addresses":["WS9dHh5J3svM8CdTqrRkXSzi7rcM5UbXKF","WWqKC1UjST6GFmW2kxgk2UTFYUeLWZC9xM","WgzfL98H5UvGyMoSC9211FLvTycxEa9hkS","WkdQVYQb2zcCkbqjCgM1BzF39hBp5fwbUg","Wav3kiN2MsQLYUhgux2nQj3mofFnBze3HJ","WmFGXsw8YpzE4ghv9VVAQarQfQMJVCysnx","WWGpVwhTgUqgwuzzFP1mB5HCzfU565aPd6","WYQ7zuWRSNaz9pKwfVm6goZed7FHWsTVZE","WbWKeaFmRRgSFbDX4K7yp73CQkDj89tUNq","WQENQN2hwxqqaaimduyNUyJm4BUZLRvHFj","WdekJ73KhvXkdyx3JbyDR79fjPvMxnzDLu","WVHCmP68YVqwoXYPQR2wCPsLaKqC4EfPaD","WQ7eQqPqWNcgSkgfn9siNxr3UqkRpTdwaW","WQKr5RrxSnVr93y71qVJc17H7RtHkmL4rR","WXTV3MAm23ZcJBr8EQf9kTzfzX8v9VEd7C","WZhyxGwTbgi2zeT8SmQDrTaQRostvY8ErS","WWt4qUPTfYbeGDUeAZRFvGeyKLLieah5jy","WedoPfvg6oKhJVwdtx5JEQEdXuBVFQDtpE","WSeWo9JKHb39Aznz5qQNk7dwRGVoB5rs1R","WZyGu8xTouhK8y2mVbTyGaEyecKLgCyg9f","WaJhrxtGr4TLVGiyq5i6rHG6TeVKVjdzsQ","WhDFUa2kaCVL47pAHgZESgje4KGWcBubS6"]}, +{"isUsed":false,"words":"eight demand churn smooth churn reform kit effort actress elite oblige final ski thumb cram trade blame pencil club employ twenty suspect dice fade","addresses":["WdPs3yQbwtt45SCCgZEoARr464TXPCz4qK","Wh7iKvL76Y7AMYgLMLUaRfy8JLYzV4Kmgv","WYZK4eRbZvVnbus62t1CNXpdtXAbFwQJM7","WT3WRpFv93J8ULV7YiT9GswQYA78pDNCtX","WgDM5YJBsVnF517BYXBuGBJVqrUsKTW8Ty","WVfPFrKkPDTPGLYPsUuukYw95LYy2kLBw3","WhdfFUYvocgVF5hN35WsJAKx9NfRfMYpPm","WfUQ1AoGWMjXfF8iVjotNfgYZGiA2qthTo","WTBJ4jUdbHaWXrPbthdna86KPs73g7hHyz","WS15y1buw36BqVijc1GJaAvWMw19UNeCck","WPHgWCFQz6WkgdjmG7WFE6erEpL8qAAXzd","WeJyoWt1DBwQLdUroraFLZpmtUJCK4ro1s","WjB3fRPhnupSdV42Ks5kr9TZ25PdVpps3D","WgoKvSB6YhMsVaZN1L9tNFDkRnnRweNy6U","WRaU2xj3PU4KbVQUHz3dGi3G5SH4C4cL1v","WbqFEr5X56U71fdu4EqAKHhFcXEs6pQrb2","WiJWrJ4hjdLPu1q4cGWsxbc9weAYWbM81N","WVKJUuRjktaumvKHcyZ96tChCQnm4uwkY8","WfMbraYEBbrKydUu9DKm53PjM3rQJUq6tK","WVyJymdMqEJ6EJtoUWJprg4LMbeUT1p2kX","WYpsD7HHDiif6oux45yoFHP9kPsGxWsLS3","WWiq71prsRNh5egZnkqLAjevCwh1UnKWiv"]}, +{"isUsed":false,"words":"loop enemy width cover pipe stable oven table steak cousin injury grain awkward kangaroo quarter adult alarm uncover kangaroo alter settle student wear captain","addresses":["WU11xybxD5eXna3pAdjJctXHPWTwMaSnKT","WYnmVG6XEFt7ALt16Nozehr2TZ5Qkrq4nb","WkacLKK3ZKuQtzqWGeKMmGseUUnfbRvZjm","WhzuyZ8k6nF2qhW1UzY8vudN5knkQfJoU7","WZYkD6HFX3b6GiJtvMvEP9sG2PNrGTgdKj","WdFf4rTd7JpNtDbJcyRcCSScobK7yTSrGH","Wh66QTZpiG1ByTACBW2EfaQfVLknNVfDbH","WNvBgUYTDzKi8BcpfVaLyJvt1MwakKdk1e","WXUVzNbg8Ns9FagSdF8PrsBmfokDdRB2Nj","WThf6zMfjye6VwZ2xU4XwZWgMNbz9XyHSS","WeitbtJmdCRkEkEubMnN7Zcva98PpenYUS","WRq58C3q2BdaKaix4pp1BLMX1GyNXzApL3","WQMzW2CoRQopXBL5UbCjUCgA26bQsk4zSq","WhoVvgd7jQmS3JfpJCrq5JAATyjXs7ybEH","WPWYx411fxVwoofT75haD4qt4wFmj4v4Sz","WdcyMK5kusQd2vj1SM4FwYSGizsjyepMLj","WXU6mi1zUkxKLBSHrBehiSY7s75SoPH9i5","WgTgcrZkkHEQNsuKLo5EvGkefh66y4YKaD","Wa8VMfkXCFzAsHoqWUQT3V1FEid3kwKtTL","WQgWE3cWrYSwFtQgm1NnFKWSphUsgvG5D1","WiEixt9QDtJJ5oXXgrs4Bj4qaJXddgKyjJ","WjLcd4hWNt7cLovrEZtqR9wrMuE2wcTwX2"]}, +{"isUsed":false,"words":"fly flight enhance slim certain stand traffic margin scrap near between truth chase joy prize digital misery twelve salmon identify notable plug cruel coil","addresses":["WVew14UqPpbPCDfSdnEMGb8wJrDLzYPGHx","WTpuxzEsvBYm4paZzdjvZ5qG9K5VaFMcsD","WSd6nsnyJj4eARpaaJWVtXnsfPMEpo3Ldj","WkXQcGjRKSvBQTP69YxJut6xQyQuR55iES","WVaRx5UfK1488DZgg3Un6SARdFY1CGosmC","WTKsfNhGFjVqpvLYjfisDCSuBDuzKBWkuV","WhKFaoapPerkRQNmqg7Wk9ojh4aEeuRPF6","WVH4rG61nmNhyXXEVGKv9JMfVDVdPLRjPs","WkbXvhEL5WkA6cncK7CdjQf5CNQH8x2uFy","WYaz7XemJ9xvi1URSfWCbfF1tjoUGihqz4","WdR1xX5rQMo8epaecmr8dp4Na74QHTz4FN","WdyHQim2JQeinq5uGo4aa32VY15CX9VYbu","WfwoUpJv6kSMFCGLxMPHW7nHTMfBcpyYuF","WZbMge7em3SP8PinkwrqG8mejhiAPuCGgH","WPqmatnywLmmqE1qcVyKBKv751Hf3AYPeQ","WNxPSGr1TMTgVtGpR8bbiWZnEZUSdC2U5q","WaVNNBv9ix7ADLziDm7qmFUTYCsyR7wKEt","WP6gzWhsEvmWKZg98TpRqGAoaASnvZ5uQf","WPUVibWEA7FK8mnWFnLvr7z6gaZVKTmXQx","WYo35FoLneJCAVfkZ8bmz7nVjvxhgxSLZ7","WYGJ8gFHB2SadHx4Nb1HnyhJqsSC8W9dm4","WaZQKbzPiWGBkyuPEGi9BmrEKHrHBz3vbr"]}, +{"isUsed":false,"words":"finish victory lazy song survey exchange addict fluid cricket unable filter trophy chalk club exact blind adult since theory neck disease normal thunder call","addresses":["WUaiv2rEjUXAiDzC9pV6mMbsyocpujmHZV","WUW6Am2eDqGc9Kz7BRR9p6UWBC2txGa1aM","WXabVUojB42P6N15q8JqbXPB6Jfgr6Hk1Z","Wi3oSf9r3XJ6RjZWXHYKX2KeNe7wmmYWkQ","WSRBgRT2Jtcgno721hjtu4aWMhS1PfxVVt","WhgmKWDXNXa3xNRMnmCDsDifJwTzVyqZKw","WT7Hg3MbNcrDRrZRKS45iakcKbYr6FGaAw","WNxMygdjcYceVKdQhyiAgA9Edzc9WKpcLu","WXMu5HQ3GJVc5GcuhRr6F4MgG9ckfhAeGB","WXS7eseC5KPGwhxbxYW3woT41NgMDQuC18","WfXsnTHGRmNYfMFBYTViy7DHcBFSjdQNJK","WSqZ5VVerJ8UNVFCoMVDKWcqrsxgqgioze","Wk4KZQdPXcoQmcTSoWiuFnSxmsgpCujF2n","Wgr9cjDxxYND8tdWTxCix3ZUqrZCcKbct2","WdLELJjixqz6XdubkA3xNyVtjUNUg7z1zp","Wa9ABhirURCPrazdj6rpgoyThXNsZaJzSZ","WbV9nbfZekXpD41pQYwmdu171zmbPoC1vU","WeFfohWCxWqNQqWoB6Yrfns1NNCLPAzRHz","WbUQTQq4VJZX4RHkCpnpbMLvFLLK1v7QLm","WQgLXEXGPfJPysKeBWSSjoDwJocToU7Z6V","WYp9dgSPM9HuPcGSC2pp1we1QJSMXFQrQy","Wfq6v3csoYhHgojrrkNNWyfWVvkFSWAY49"]}, +{"isUsed":false,"words":"type elephant noise admit public monitor tower helmet pelican rich artist luggage accuse slender sustain piece electric kidney metal fire mushroom ridge hole kangaroo","addresses":["WitMdgaLJ8B2xBUj74UA7xp4x7J2N7fZsr","WmX8ybHJD8JNYiNNJ6RFcqCpPTpmRxh4d7","WmgukjKJcinRLur5fs5P6tZJRV2BT91MBs","WSdgMNczUXjZH41vrdXw8kP85D6sXb4sVd","Wgaa9b9JdAgNCZr2api78K25zhS8TbBdgE","WmcSXRYQwmff6qzpk58es6ovZgSgj1fweq","WVZzkUo8jBXzgNs4apb9bfsCksvGXMU8mg","WdeZygv72T3EKXJHAFjxPpt7RaVowavdsr","WdFMamGhBM747ZqtKKDUrU5vts55NQSFjt","WVjd6ohsPuJ76hjtRrDqHXb73U58nrY2s4","WekC9CiXohbr26uaxG47iybG1NibcNog7h","WThdu24J6bvpFEecj8kd964YJaoFEdiHAF","WT6RgKrXrM9A8iXtdv87EwRZ791LZaqAVP","WgSJxUMKkPk2WNpiQ5ue7boz4Lz6u4LegZ","WimaKreAbgHQmg9Y8mryGw9RxXFBTxJw5x","WihNR8JK4GuBW9HH4rmDz7LPBxJs8mTGgh","WeBSU4Yje4eC1d48XQbNVBAMwFZy9LvqBW","WYKaxJK85SzGvGV65a5bexVYiBqJhxVGd5","WSFjrQkMYjY4xkrPzA7TD1QP88smENLMte","WTVQgxBJ5WyN4bJukzHhahHVYnxB25cF3F","WXqyRpcmidSmTBKdoGdhQzcED1izRkmjqF","WZDmGb9RE1Nx32SqmnoGCUhfHvRQfHjLM2"]}, +{"isUsed":false,"words":"lucky box valve smile icon gospel jungle crystal palace become color vault october stereo please borrow over sure decorate uncle mandate belt search boring","addresses":["WYVzTyrXJkG8cKnuAE7hMPFqcCiFjGL3ab","WiTE9Wea5NzozC5W3oRtts6y2sXEf6C3mG","WP37M8ey6jEyfsUPEbVAbAGAL5Ygwf24pg","WPJNBqcY7TSGFBnurTj5wbdGfsUd3PEcEL","WakFm7ozt1DbesxvrZr7FEDbLjthmC336e","WYKL85BX8xZ5QZR1E4ipdfoNNByZNkQjs6","WXMazpu9C5XL1taxg4dbT39N3LazBwXw7U","Weu4aLVHkH6HQrzFDQFBWZMyGNvKi1Qx4C","WcBtUqQ2Fk9sLa3sWVgafdbCqpNTP95X7G","WmBb2GsraPWRLjduNQAHbQG18vr5toR4FV","WYMPjV4BjwxNw5Ev6eHBUP6d23Syo83cVQ","WWnnfuMY2FX5hjVCCMpMN5fQ8eQTVxDoi2","WjeWTSE6gP9TUFWmckTmAxBGYfJxuc9Dsv","WX7ni3yu8d47cfPJyWE2EYoPK5TPKqrscK","WbaZUEf8dAdxMWkNG6MDbHoUYT6q4c7vTP","WW7MQvWWeFfyKjAyW1NatyP3GHBGQsKuvf","WfL4p3AzQf5BCeTQnxaw1gsGBoPbmnA8cz","WeEWidAZqm6Goh3myjrRPBYbzBpRGCBdLf","WZFtjKPqXo17F3Jsng2ep8rPBEANMQsjqQ","WmKCKXyUhHBMDCuyLfYcpPY8hfuwgmv8zX","WWapc3rx84a8NbWxBLMEh8jwmkL8DexxM5","WVTipVExpErsFjqwjg2KQfApprCfAAsH98"]}, +{"isUsed":false,"words":"rough era slice happy garden trip scrub toast certain dynamic tribe material shiver portion skill inspire change young capital brush replace wagon language else","addresses":["Wmg93R4c6JZaSfDteqh7XFiUPW6BWXpWdd","WbDg4i3DZRnYdS4GggWYYENxYdxfR1mggu","WR8NkXd42tVBZpEAncZvnAfmJryCgDBrar","WX5hCTohADFxGuYQN1qqwE9U4DmLXdFJwA","WYZUM3jFJZLAfcRSXnD29KACXgoPPcEhbp","WbUzxNYxpLyrZ7kZTQdvH2S7cQQkszZWpA","Wg1eA1uG2VRcGkDR1oAkP3SyrCvfKxyfSf","WQtf1HQbQHCRbYSFKehnNEzhqanJcbNRp5","WUyuyj8zAbEEfmA9MhwgC4oDkCt1BjZ7bq","WjB8tcbmC6QrbadB7x9tRj1WCP3imyjxo5","WmuAcG2wiSMs7gkao9Syq71GeGyjVDSfMz","WkZ1oGffBHyq9TGVb9S5aCvVj9zGpywdhY","WerGsj6Eree7RPQxLNQQE8NCvNySDFKzah","WSmTmUB1mLEnXFQ4YPqwe5qUmdvgkCYSyP","WiV9VQ5dJjrujXt5qX5RPcufmzFXudehAp","WcqGeN3k5hrdDJNXthsdzqcG13VgcnKG9N","WYqYbaiV7GdB9TkSwZ7CSjQ4HPkNVcbSSc","WWjgUsg3RswjQNzSWXrMuUzamVc2qo4ECL","WWBak4rD2gtfshY3RcyaQdDPjHWM7dj5jx","WZLYPRuUGBz3vsLhZjGaEzDsLDNf5yrSs3","WZR1ALNMaxXNyxxQdLWRBYD2z8yUj5wy4t","WU2MmG3UE63hz4XkgtDR6UYwhE3TqQpVAE"]}, +{"isUsed":false,"words":"budget spray citizen pyramid purity neglect vast staff cute game little cancel daughter ride holiday crystal treat bomb replace struggle video spider where elevator","addresses":["WTn9Y8roD63m9mucuBBSjTQHKvZcdH9XkT","WfCzPaqakkPkNamcALYNhjkdy1gL49VigV","WcHzhdHXCaqwyZ2t5wWJ5TWNxEJYMmpjL6","WQoZbStcBBTdHcU28scG4pJjnXcbkPLW4m","WhJFozMvg6TA9eZPo5T5TfFV55XCyGv83U","Wdx8CimHa5auzz8r8dXFzggAct1osGHUig","WdnGkyx8tMb55xQnuiyJ4dqTx5brjegjSz","WRNAhQPNDJDkL88VMCsnsd84GkjW3bRTtY","Wf79nz8E8gSf3LAXJsx5EL4GH6HaQWZ1da","WUdr46RNXiLuEVMUXnXfYgZ38quVVmbWf1","WiUR3zTWwYUAWxxVo6PNMx6G3NevTGQdTD","We87nzbHfcNPTNH67wzaz7tRPEbe547u6w","WQW85huMGj18GQ65dzh9cyaAXLFZDn49T1","WhGwmYQf5sjUfQN6gW3EErhE2SMGLvF2r7","WYn2vAN9TKPABYK6r38aZAXpezPgRwXFtg","WQNg52yDat58qGUqpP7KWas5FRKqKgQxvp","WPqFJzoWp5r7xsoKiFTborQ49nXdVs1ktn","WhbNcHmSiAM8gLEfdyFrSozqj36NTgggHf","WfNpEmXcCkw9avE8m9gvgB5SBtiQ4f9fVt","WkMXLUY298PNmGf82zBv5qN16MjK2A3Z9Q","WbwNa4kHYXZFZWZEhqtew1YdPZKBYWEqXU","WfG5VZpwQvJ9sXBxLqRVJqNmRZ6i6jjw6E"]}, +{"isUsed":false,"words":"mutual fat chef pepper leopard release animal before license joke another fix thumb merge youth gather edit battle visa tray flavor exhibit purity kiwi","addresses":["WfvTQYwDizaCkbTwyhENvZPKnWuFVeqVcX","WWmDz7cUp7XLYBUuySZhfDcvdJNAqNHa6Q","WgmN9CHHJirsfUsz55icWZnWKfmgE48acp","WNmvJTJ2z4ta7mr4kYXmmV4MKcSNTmYF3R","WT2Z88WDsrqPGsZwmR3Ti842GQQuSDiaqd","WaoqQY7fEC8r6UsEFtN214yE9jFFN1FCrY","WP5nA8YHqdCUrWuXuSUtQCBcuXLXmJjQkp","WZyJDvYxgRkg698gF9RQR1qx62X3pkyCme","Wb5moyXC3qTyFWd8e7TbXiUBEh13FeeRRf","WWUP18sZvGfp7aNN5kGmdUUbBAqSYS6QCx","WckpwGKM483rNftzFiVp4HSBUBRtD3UydL","WaJouVd7WnJvtL4F9isChCuMvCsxxccG5S","WgL8WtPyZqThtxJNwNKmDq2gDWR4kuK692","WSeU41hLLk7bsFGUeu61LaNbZN9DLcaap7","WdsLWLfLXF4LDQuiVfM5J9WHCmuACGxWyy","WjqhrykKi2KTPEykg3kUsKxQhh32GMLhZa","WmnWhe6CjJ9wBTWwgp4oyMdvbAPPT3uAVk","WdCNP1FgwofHSeuiQMd6QfHgWwKdRxRaHx","WiTK3d2PrAdnMwaBwPe7cN5aXCUcTQxYKq","Wad5ipsFf12paVdJ4WWH13gqJWf1zJoDFK","Wdc5pGw6Lber1gMGA1ReiFt8Kit1qP5QCv","WYifhywubG3bPHrsZEJh6dtekcVAcgvM56"]}, +{"isUsed":false,"words":"dose spatial shed east delay retire print rude ozone badge festival supreme husband manual often unknown acoustic wreck tennis catch access rocket canoe silly","addresses":["WmWpmNbArbrufXX1DWjUxzPPn5jkgHRtEJ","WU6oVfVbgbNEDpoAHDRdc7byLwfhNJ32A6","Wa2GVgCwBgD4henSwNzLdHDLrGmyRVKZZL","WPSms8BRVyA3VqPeVAUDKv1BRAGrYoQMNC","WW8nbbSQpgjMe73MHrwDAh1u2docxP9TTi","WYYFGP6t4djtWFFDXfg9yihDe2j7iMAc4Z","WYQppEGKQexCSmdeZdgR4hTtbRpEMHjA5K","WgBAtr8uKTDquZkUKv2M3mTTRzigq5jHm4","WUtc1sXpz4EgwJGztT1UiCYjg7UZqaDTqQ","WipyRPQujsnA3UKs8EiFc2TnYC9WXyD3mK","Wiw8EPEbDJAtJVvLQJURqFBw6FqXvjkuFU","WdaA7SnKCXcFSDFhcVPxC5tGuCnjaUTGPP","WbKn6KtNXsJxpnscWizV63uzur77ieCGnE","WcGJpGA5N6YuFy6NMjYYURyUGPoePcAzR7","WRh9ctdup5cictCqVfB7qYxHTvViTJFUAj","WbAHPL7eHX27ACwSEtX6Ad1TCj62jF8hX9","We1MqwyzwwxCdXTNLHDDiAtjXqpZN3Nkmv","WX5zubMAV9jA4Y4Cejs4yDam7cuwKCJB42","WdWeGJ9zEMUB8gyy1BQLfVsEzPrZshULyj","WatZZYf6iqbGbuJM1L5fPA37RbCujTspNf","WfRmYjYNNw5H643tU7LDJsKovnkp2BdJPG","WWmBEFyTNoYpY2VDXdDePgxR9NxmsMq9sF"]}, +{"isUsed":false,"words":"siren subway sauce weekend flag novel where bonus grow artwork glimpse matrix pilot nuclear vault rail vocal creek category domain addict giggle someone sunny","addresses":["WUqGFLkdY7mWu174v5Kypcx6cuFzm34R91","WR7VCBtVoNiEXZeFzY3pmX9i1pwinbfFro","WPEVY4tbUfHgMmkyhfbat731YWVAmUxHwu","WZyhvkhaoCVF9M7kwfY6hEE54KCQi6UFUc","WXmic1oEB1np1eZPpUmCQJXtpkXWYt9As5","WmedLXxGQ3rMUZ5NzBmp6Bn2C5xsHdmh4u","Wm33ZN45kNf8P6GGpPY4hSbWsB3d1sVCY4","WXBRVYjsY8iYum6Z4yxE2yfJijC3rmv7N7","WY8dKiWrPZqWGbNwwDKCviGDZYMysxuLyG","WWSemJeHpuR9VnvuDt3ju7sTMG6XcC8ELg","WY9aM9uaofXspYu4fnZEnfrtyDudMDs2f6","WX79rcSMpQVmHbHNM5FZmUZkqCRQrawzC1","WYGtYEVPhgK1Ea68H4S1uoQ2ce8zUoh8W1","WcJKfF4ctVYurvQ8AzaByq1mwLr7saf4dS","Wm2hj9Xyt8atdiLkhgSWkLqQCPuhxtyz8Q","WNzT2PcucBuvbgyefdgUKnkrmwhn9UGGUU","WTjgMnJUM44rSVCQjHbTvnCsCkqwGLHX99","Whc5ic2jcPrjdkoRPVNYBeraKbHaQVFpqr","WmGxxVGZ5M8ZWbHHdWF8hsGwxQaYfFHzif","WXGb18mUz6ELWTbA9Wci5WKYfZbzw4vsgQ","WQnd7y1bA35CAo6WVaHgrXcE2vTVDSb5NK","WemTjHBXnMM9Nhwthb7mLzoNi6oFxSyXSo"]}, +{"isUsed":false,"words":"enforce surge scatter provide artwork category cereal height coconut viable tongue reject ginger release opera dice outside olive model debate grit buffalo smile later","addresses":["WeXc9dsHq23j9bxHtop2AuNEqfUZKsqDhu","WkSa3nGZTFu8CwXm2MfR2BfU9CTKqSGLTf","WmnGjD5K9PYzmZMZcjNPjMZCEHiPQHuBpi","WUZgNPLiLuivtcmQa74DvmM3ivKiZCJBYq","WSTvKE8pUaPBpT4iyeSJYEgwT25w1zqJ7o","WcQs9nc5opeEDbVbBNFGFpar1YELR71x2p","WT2WHFDs3Mbg6MAFwFJQoymYmoPswaArNN","WkwikdU5opsS3evabNyx7EQg14z2vE67bP","Wb9uMXVffqjXhGc58tZ2LniAbeNXAiRW1X","Wdqaur1mWLd3CFE2vqBY8P3NDutPS9e4Xw","WdVwALkMKvAXNdum1qHuU2KcBwMHtNhbxn","WaM43JzrnM5jSQNYGSySAbWr45EbB15ouA","WTSLwUk5VEx3FT3tsSEd4aAddteHWEWWY5","WkBHvTrDTXo1SE6qepKEYdvaVLNpSXcxZk","WbhbjTrutbv7XrVda6FqVJSZhN4ARUb5tH","WbYkLub89NvyP6EDZxrybMu9AvxuHxGBnz","WZGr2R26VaXre4e32R8qGkBakNeqAMvvs9","WUSfzPanvqpUWpyXxDiiFJvdJ3PHLmrxUW","WhQBJgLBLErGVVYBES5DZxtW7pjBm4ruQb","WWr97KMoSTj6Yf9yckMGfgzy4B5LVSna2y","Wb8SDbp2zuobTC2qavfhLyvCVagasnFcBC","WfHr4SB8zw6UMwiANPPEnBE8AedADLWoKN"]}, +{"isUsed":false,"words":"mechanic shift pioneer antique common penalty donkey device insane couch prize mimic address fancy early slush sword lucky dilemma token outdoor tonight lecture sphere","addresses":["WWjCeex5Ubu1zPRPh3zkJfZRtyABpTdRKj","WdR4PKfRZe8tdkUkQLnrDj2J9WB4WueBbg","WkcQg2TVnC4WDNgwKENg8Bjd2t5XaHMJ6G","WSpf81QD6wwXjK51Xwua55ciPLLDBPtKgb","Wej6m7gmsSkAygtECwtXeCH28MxPbQUP4b","WTmjTqgp1uxkvQWphwJz4P8pcgTU1U82D8","WSSvNUunguuQMhRfCnYn3y7uFJpQceYvWQ","Wd5UPu3UHQCGsG1mDwvQpLqua3eo2GuCRn","WknQg5T81UTGVKNnfHaRyDAfZH5NqcMuYS","WZSBWdTB3dmTi2MLWhYzRj673hfi8uh7LG","WfVi6y8HC8H1Y28qaTzxFTPA8UkszhCmY4","WkfNwiY2wzei8aYv7ANzR72vLFTDZDbYXe","WbjLZXgV5xJEWUYtXxBjcEsPtsdV4SfnPR","Wcaica6ZXU2EhqT7BxHyezKyLS7pWRwPZC","WcxDaG3iRmuqxrJNM3f7GvrH2yWoCF3z3x","WVhB7tDKCbotC3FTJGhZ9LUmWP4v89n2vh","WX3DpqQHRL14qztXXvqfAD4ExKo2YpmZTH","Wf1RyNkY6gb4Arwd74WdQ2yhxrQCrrZGYw","WYXbDh5t1AgwDLC5sKCMWu4Le1hE8cTdLU","WVTyohYAqaxcrqzWGMAjARU1ffrfcmepDX","WZHC7CZfnXjgAuBt9yTDyoMqiPK8321iQn","WknzkyyLBNPMaLZs6pujh23URynWJtCNt3"]}, +{"isUsed":false,"words":"warfare gift bar gorilla loop tennis scare slight royal balcony turtle actual knife that rival blame viable flower shaft brave ivory tattoo when heart","addresses":["Wa5kG3FijAxZ1aPk2pvTSdk3Z3amEiGbEo","WWVdARGxyJQ54zNuNpdKuPJHfbvttHon2h","WXtED8ZNEEbd64QnVuaG1s9X5WmoRzYDhf","WYBV46HwkxrwbAirnkff5ezP26bUkdRGAs","WXW2mY1xwbWfq6oRgWFfLp49FaQV2h5LyY","WePrQdwxWv7Be8qaPqeqRR1dcjqKUK9JLq","WUwcLmzKmoAqRVUwu5R9F2tT31nr6MrYD1","WQDBBUY1iZuXSCvrNryXVdngkQmLZqrwxS","WjExTHPuewhpkTtcinnCyBSoJgn5vdKWCW","WiJv7pKw7eQB54CaMZkyujuzTRu19L4n46","WQo8W1ZTsUa5Aq6mb6sRtVHNW4Bh3d1skW","WUoSBwNCkwzYGhErMURDh1W2RvnYxEiHtB","WeyrAajNCa84XeuKmSD1GEEwRTNXUQGk5Z","WmWj36UBiBuTxPXsnCXZFR5MYxWYMdsLjg","WVUsNZbM9ADtkJMvk5qPF2j5jXo1sabfUD","WdXosGhGNV1CQqFUv4LQB4FW8ycxixNoEG","WkYmBxRYhMAhyCpd6qdiw5XTCLKLFHi6PL","WPPLP3pNPkuBEpDQHga8aUH5f8HjS1ivmU","WW8wNM3pVxyqXCBBrBvV44s57um8RfVakp","WR2dTjqSGN3uNzRowCVLu6bgGE6picMknV","WYwjLGDcdZ6oYEmP3grrEYwUcRmgsrcxLY","Wds2vRLv38sbZtKp9CwzRuPKeRBU6c2AkM"]}, +{"isUsed":false,"words":"narrow improve stay custom supreme project frog refuse misery enact scan stay reunion photo sand cruel swallow obvious bubble coyote fee crystal artefact desk","addresses":["WbPv4aMx2xyAZUVioZcPnFCZ2jpZhNfhHS","WQuU9xhKdXoACWeB8TFd7vof4Y85sZ6624","WmXXSZrrgQH2Liz3Nfu6T28Q6LS4gNAGoD","WjWUwkomqhpaw43CkpTMDhG7uapdXuufGi","WbJNbCnvNxGrLyLbzpWYPBFBivkMwyVXh4","WTZ9tcWKmQ6dAruG2rme5vFaA6TgAjtuKE","Wm6NvjrSZ4mq5uv7ufeHFLGdCEFVYgB93z","WZXi5hC7uyG2zmQyAtWN1XMKnmZyMa94Zs","Wc9xU15YCHMui7EKAG6TpKptmhXNCyX7DK","WbvksU1tLUrhh8Ut6hVd2mL7fhbLkgRVUk","Wht6WmFCmBPyLQewNb1rZtvefax7yonmfR","WmSKxrL8Ut8wtjh8AGQXWRFjWvmxLXBL22","WhGLkTrLsY5Hkbp7athjTyUwDmjTB2KEzL","WUL24yW6jvYpPhyJPQBoC2PzWucGPKAeJi","WY5Sv4AedXFR11zjd3Bmux4p1TZwTecX9g","Wj4WNyWkXekJ5kuDLEXFuuor9RfdCUk8uo","WWg2ZhbYCbXXoegitsfnV3v5yyed6nNohH","WUW9AQCtoGKEXMLFDwWLLh66Uv89pjF6nH","WfFfAXwcjPfYHK9Qw4FkQx77jsFzn5tKH3","WkKqcrBw3LEM9DaDM3hEByhEj9T4HWYJwd","WUNYufJByforJME64P3GA2hMvWBQHNMqmh","WgrP9J3FPampWPFvMNDgzXD3oiQ2DNbiqa"]}, +{"isUsed":false,"words":"skill garlic scout victory surge old term nurse fox life where poem dust radar agent junk tool lawn economy stadium someone jealous stadium doctor","addresses":["WeNMcYbyzhcKjnwoHTxiJQ4L4WhL1WCvow","WipgPBpnXXpZLcwTzwLrrbbxrVkXLmE7Gq","WRcmaihC13S86saC79VSitCPdX9nvtrVe2","WaD6fzTrDLjST2Ttm7iXo9G2svLEcBN2HT","WXLdguYW5EvjV4GUoKJCHNFJYtatCgVGYG","Wd11CjYAMqCye8Z5qKzSUwU6EEa56kBV6T","WQ31iV1Lh2hxf2mCMJYqXz5v98A1Pd7DKs","WPJJ3WewQ29c1cdBWXHBf2WnQAMTRakjSX","WQHqoAfbgreQWFiZVygGSdfNVLmnp8Wh3h","WfXpn1uCazFo2Z5RucLm2qnr5uHVJS3j8T","WSp5F6ynxnixkJQ4f8LUmkDK2LSTFXQ7fz","Wcd7qXVmit8ZGZVhHFcg7VR63nKqsXiAvK","WabXwUBDHjQetA5hDefrXaZypKrMgCy9H2","WQbQgFkb5MBob6FB5YCFC1q3Ebut5smAy2","WdUG3K9Fr87hJ6aWa7ZHkfnXxJrYwGae34","WbHsHgL4DVnyj64bHoxUFuzALVd6H25PG6","WkbPQKiqYq63NPv1akhbNDS4TTXamvrA8d","WjTnuLFVvHB7w5iyhf5V8AvkXayRYXLVgx","Wchsj5U1C4yGJqJ6ykcR8UR9nn9yhMKTM6","WQpmms1z2ucVJUf1dimWtJWvpaEriabHP2","Wffv4pLYcUoNenFHDFPSEQrHBouAqca8SW","WYzK7adxhhqHYMkZ9ytTDFjratcJJmDTWU"]}, +{"isUsed":false,"words":"gauge element artwork chat tenant predict provide patrol bag kit strike humor hub nurse demand grace dirt point increase crack pluck season robot enable","addresses":["WZZyb3774yftx24VzqcfeMAST321NCCBiv","WU17miwuUPbBKC3Pg6nvk1xrPYr559hyEN","WT2jGZeWyy8UVpNiXMGYB35PGTdvURzidm","Wcsv5YCViaGt5fBafkLw871BiUYPmQZATo","WZgLtqZPSUTYY9aezZ3Hyw1WajpQUpJYbq","WmTTvnqnsvTVu2Kk7FjH3LYzuJ4VWvPqua","WaoLXxCvwtV4oq51Q4Xp4stbCyPckcxjgB","WmvTmtWZZ1BPUF3pcQ5aWHBPfXR9Eq5MUm","WQSVsCPrbhudxWk1ae97qSKJHxjJrjzzfa","WQuK2TxnvysN2p5Hb3shNbvbNeACDaSMYj","WjmmCvVet9ij31fwHYyBPYaYiAwdnWw9Ut","WWyqYfyP46DiWz2EN56wXpYaGyGd4fBjwt","WZhEN6An3hLqhB5ufvMkTUXTNDFTrjDNMT","WU1pe6eMpgBUccKdAVdMr8BjEcs8Uoiceh","WSSgrnVoa6u86z4z7fGeLDPudtRp97dRKs","WZeVAtAWthXh3HmQ3pgyFvco3QcuyxsAWK","WX14GDj5HNAiKsLef9fVYqWWq72T1suzdR","WiwhCztJgFafuwtigvdiVLC3bUF1qxXznY","WYB6XsMwUMfVceFepz8PQCagCvjGGqWGXS","WSSvjoL5AnikysaFF4RXdSMZjdivJtbtU4","WQ1kf2GmtQwPtZCvw3V6bvFPJoz3SS17uk","WXEGXX14a2DmLQtAPqZH18HhDkBT6V8RtK"]}, +{"isUsed":false,"words":"spirit script arena drum trap sentence pear view start cause quick mouse else blush live whip monitor protect patient emotion range lesson tired dumb","addresses":["WddNyTTqyG3XBfrzxrRkvCnCEmtZ4VtjHP","Wj33Prjohmc6ssihWKxABb9hWr6P8wq4gC","WaZtp6d6Z1mziK8YvmJSogfwFJuGyU54Xq","WSaEAdCxhDYzLfufmUVPCNWbmtb1tBejEv","WbKHyQckteRxd2FY4V7HaoESZ2wb7Ax9di","Wej6qH15GPeBEo2iWdb7yGNUM4uuPs66iM","WQXSFgDDSipKiTMB9Gy82LUxTXk128qqD4","WSVrrWaaM7CqmiofGXfireBJdsitf68QGg","WUZGcwatUkEjQeDFZXJibevPANrRPS3jNt","Wd7ENbzvKeTccxdhv9E4A9G9t1JL6TXs6S","WQnQLd3GpoUdBmDfe9ajdi7KTkWtSyFeC9","WhEzJdEXCT13k5twqtYJEgrCjFWzEZN6NQ","WZ2cZQuQ1mM3n3QWL6cod1pe2zoX9f8dER","WRfM5pNrYkLz49p8Cqwf9Non2UTuvc26QH","WbwfQsAfWvRhPnmuf2zzaajA87eT4NqJvv","WP2nd8Y4YhVAVtDcQLpBqrYzuW5saNvrG6","WSuMHKP5v4BkngYT8Q2cB5jiZSBe9HLfu2","WPnu9kZNEByBuXMzao6TbVa74m4G5PwJAY","WisS7MfFY6vqjaSWByEcJLyKtZggbwzhax","WbdJqhoQkofoA9j47QLHDXxnUg1dipKok8","Wety7sZZZtMCaBK92MUsBjCMic5HxiGuxn","WR5x8yGYX89WNRYH53fTrRMi8uZniU4odH"]}, +{"isUsed":false,"words":"group sign invest broken blush photo firm version simple swarm timber whale tree airport hero hen olive clarify relief island toward erosion size day","addresses":["WkXbA9Lb5GXf8xU88DnuxPwvshVovQ1sJ4","WRDi1eRcLEWWNxixdwTJvjjHD5C5jXuN5x","WgUNvfyEjNEnmqVxgrr3m7mRnfw4hXWw2N","WhvxupQRvTBcTqpMTaR9hD1csWQBoUb2MV","WYW4JfQLgXQdddt2jBUFzEqDSypUusL99X","WiWoBURhSzbusnsXLHEQFUDUnycMWgNGZJ","WiHTeBR4MpmWuzw4vk9VAj8G9SYYqQGCDX","WcvqLvyD2AeSXY1xFAoAfDjEMCjutygUxS","WRBYjzEyuRSy9p35EbnFtrfPH4eh6bQ4kc","WaWZnsV81YbcVHpWqexRpcU6khtcVtXBPF","WgaX4u7HPmP46XWFFxNTX9ztuXvTpsT2Rn","WVHsgZznuk9SVaAnRe2EDdhYjaEpqmA2bS","WZVGafgZGzfSxHfZa1NPBMppEhuG2XSeGb","We4AHDg2KFFnHDfZVZdCB2Z9PEr6TGwisM","WP2AhLL1CQuzrvWdWZXzxuJF32sdoNYjpR","Wf3eS8WmHhZm1asrm7gQyEd2cpW6kK2eKd","WVmja5YXP2zMJN2bprPfm2BWYFCActoDTL","WfPxfKRnQbgtktZCem8fQb8dYUvuNT1Wno","WkNLBqvRqo7DBX1s1FPHzaRgSbGak9GnDf","WaCVJCyPKgkc65Dr1ZzNpwysiMEhJJtXMq","WYib4XjdUtYwsVmBsi1H2U5AYf12D7HtQ3","WaBfwx4yDobNaWbn98yF96JfvQbWFReHic"]}, +{"isUsed":false,"words":"physical blur motor vivid sock moral slush glare imitate rebel brain garment farm bronze traffic erode stumble bench one shrug sting broom reflect fee","addresses":["WQX6ReL5sz8cvgHPNyEcYrKb8wCkwVHD5o","WUxzXyRAVcqyZH6WNuWUfoJq8aNo5AKQcf","Wer2zpZT3gASMiadMuNWvHSU8vE6ugLFE3","WetMBNzXAtwihhqXDmp92RQXLCjWBTe6Xs","WRpQnD6wfBLdVhvHGpoXgSTYr1mKEH21zx","WcYrS3uRo15yZu2iGwUkqVnaPMyYvLU6rx","WWgAuYCdQr4mLRgf7zBHU67u1CkJdRbuhM","Whh5mwidtMT7HyfATbNYFf99bi1qbhQ39F","WTiyeZzyqSCD4aDULUvbNVARmidA3vAdf2","Wd4KFBRReQ2Rzqp99rfWCW42xEJEGsWRxf","Whebnis88yhKq7QUW8nmnofzrkodfokQtm","WNvazavffjRRLTqR5AT78FWjyb4tJwtqh6","WR84JKqZqu8YbE4EQudq4EwEX9unSojym2","Wii2LyAzv92eDAV8xQWhp1uq3D8fuhfKkR","WVKxoUEXXZZvp83K82qcvzgucSdpR2yPct","WSyNotgAsjFP6gDkNU1rJjaX1hemUgXET2","WRCo3PqJbG3EUn5dWHNKbHnszBr5kLkBEm","Wi5stfTuwMnhjvymg2TabHqxcvTfDu9ZDq","WPJXrcjU1nLAPadJL2tjRuNhqHBwcGEWhj","WRsKNgLWdT91KBVsCMNaEHX4LFTYb8H6pV","WhhDDvQrPHdD4bQt32e4Q6YptSmjZ8qyxC","WWb8SVqmGdPZ5NPVRFzEBrKCHhutJmNc1c"]}, +{"isUsed":false,"words":"treat laugh air excuse problem correct basic album appear knock visual spice ocean industry vivid turtle gauge worry current train state main liberty bean","addresses":["WmAv4igiSAeAMaFTNTXCsxeYN46gwWgyrt","WehjfRd1uQ2nSrY9UUaycCr1yusP3duVmK","WQkUZwuccsZFETmmb5Su4xYqHy97wXyxhT","WgrQDSCcrY8xr9yiLNFCxo7sqDNgCvKQ2y","WaszHR3q1cTm35TN1gFxmV8hBtFe9yKUyw","Wmpqnk8vtKUTC7Xy5xQji2FnqKrhr9jnJT","WeFz6TWseH4i1caGMNiH8hCDsgFcLUVU7j","WUwCwBEA1Kv32Nxkp5UpKsnbXnis3ZRigu","WaNZSztkS7NkWXYAsqeRBexanMuZx2W7Un","WkbdnsyCiTmBDA9ecYiavtKrCK6NSs61RR","WS134YmsskpL1wfnmZ46BEGm6XncdYrpDT","WRNAby5woJ8NuBnpMomyjVScFtS6mmmrGv","Wdbm4q7YStbXcPZGhMWcXHWL3kX6Hucvvv","WjbPdFjCUjcEmBFMHtoebkiUiTey8qavRg","WgWQt8oocWhPLCG3WjVmbMozWbUT1gbHzN","WQG5ZoAWtSEWpvWMs3oP8XYEKt58uvjU8Y","WYj6qr4qkRZMcD2RUPHHJ8WD2xD1K6qYnM","WkNrnCGmmhXSS6knT8MNiDwvNB2Wa5XTy3","WcVTZefejvuXwP6M3nhNb8vjwiZAsLLd7Z","WaRxD8LMY3v9uBhfTa7SXbLFM9D5jrQpdb","WbPZ5HA1nRQpEP2ribjonS6Tz25EVA1AXm","WWkrucK4NM5rAyp2Ttvg6LxM4HnntBhsfH"]}, +{"isUsed":false,"words":"defy unfair bullet often device deliver borrow carpet blast toddler analyst uncle smoke afford piano vital marine fatigue hawk aunt merge outdoor opinion entire","addresses":["WhquMe8PECDLtrZhCZreQeFvfRU9HBtNhu","Wmyn275US1qqZtvuXc1TPjvkLbRrGAK9RM","Waor9kRUDgrw28WVASoJLaWvd4ehEeKF9E","WbYcE7uQrCNNAo1DGXWRfcHiCU1d136zHg","WPbsJUS3DKfmLLJ2XxzomTya2n1QEq5Hhx","WdTTCcwGkunxfr5VUKthEE91WWuvNec6pq","WWbb4pbgWqHuqaEutMJjw2ntbMYjiD1Agn","Wi3LoyuYE17ZMrpC1egD6TTCXyc35WzN2P","WhkKryMJv1x2k3H281Ru6wdATkRqZnQgvD","WaDh36pKFZ9A3zqMK1GNiEfUrdKeTdGP7n","WZPpGMLf1eESVWHgH62527acTf7RsJ49mc","WTTjzxEyFr1yGcwPzGGJxgnz4sxrn1QXdB","WNqyGvsQeEsT3yCiHBwZKeXTR9BVJ5Qkdk","WPn4PWYxGMZqMbNFk9f7XfioMAjMnbLFRK","Wj87KDtNQaXDUPehnmStPsZgyd8cAscB9M","WNnFyFiJ34GXNq4VYWvvwjV2bxbpAvAT9r","WdA1oh6TWs2daQjghykqVdWTufUq3RUL29","Wd5rhtXWGvKNJSadidx3BkQEkQcmQCePrf","WbJQpYZm5SR88KqGpLNxHbVNeFJh2k6A7r","WWa8suFbRccDm7giUDPrRUUzGQ4dG1tH5i","WgDydvZza4xSC3r6SEKfWzpVG6zv5cWnuf","WfYLcUvLLTzEsUGCAJmjdnawgLHD5n8Ys2"]}, +{"isUsed":false,"words":"mystery bridge donate october forest year scorpion sorry unknown gesture rally flip shock roast few width wrestle morning loud tiger embody miracle sudden turtle","addresses":["WWskBZeuKXtp4ZJd29SZAtTGzKuUp6RHXq","WPui8t1fQe28rndQExUfzgbLra5YYFbfcW","WVFZgmNViA6NHk5ZWPFKSjJqBDukTeRWE3","WfETenFcTuogPDbzZ8LMS7c6h7sCivDeAi","WZvBM5JPjvg415Fv5hkLNJo2qSLVf48cVZ","WXtpUx995D43wmN53XC5q1q4UDerBgw23i","WSaMHiXZsHza8jpzApdFKQsBYm4CAHbbxo","WbcnrX4mQZegVSnjVGzW3tZEgzzESH5xqb","WcjLkfnEdzxqagqTtJDQj8Mzta6HE3tFWg","WmyAdbCnKNL1qgnKcWamqWfP8xSMtS6Mm4","WkQzwLKrzmKtxC5siqZ3SxwDEugrbtvFWv","WXdicCjvFZRna6eSW1XscQ5mfbUNJ9UyEz","WdaZkMXAmg2PCr8fwZZ7j5FDqvAHnQaaBy","WgBegLxYF2RJQbhu8Dzf8NAY8iFJRZB2sf","WfcHKuEwpoooXDt99jNby4dtWt2Fk3mXFs","WNsFgJdi1RhFJftxtBLXzhcKZXEGPQjghL","WSbpMcV4VNDiVevF4W26VGwn7ePC2Us9jC","WZXwP2s3EvxveTCc9gwYFbVsNPfMHBJUnz","WbbfXiFHw9S9i5yaLHVytfqmczdHFnhH3L","WR2gSTLmYWUN6mF2HuqqaCSKz3JsAayjUs","WX2iMK6igjkVfetCQ1DyJvx9uGm5aJ3ATL","WiZsGUZkaL5TgzehNLF4thvDudm8QHFRdG"]}, +{"isUsed":false,"words":"satisfy raccoon humble march keep consider thumb deer love poet old skull cry curtain waste increase casual tobacco wide autumn ticket soda repeat zebra","addresses":["WQYNeaorKFrNr91U71s9JrnzcJK6opxCnN","WSJMAvcB1riLrkhS2cegwG9tYxjKUxKcs3","WR8HwbAjFb1BVntwVnmwXtTvRRVmz48vUJ","WghmvP3QZ8VJtTtn4kReBmsUXq6emetdj2","WdUGUcSt2tM2EdxbGMYdpCJKN3r4vqshBX","WQodTtanjeEuHJwLgLPGkHgRKcwZgKzztc","WmH3zSqNt4EcuSQXtASShyd7bQMGVLJ3pV","WgwDhMfBesUf8Ughw7wdSFTWzPWVezuqQo","WUQ6o7YzyUxiq9CVeCt8WRrVwjcHPoAT6T","WWAFNPJ3Cx55TvYSzwPwE8E5e8fUBtjHNG","WZUjgzBRZv9ReVjUt3UwWB7qvkbUuUroHB","WdK7JJtim65iUHvBZUy3juicLo9Yi4QNih","WXSipqbYLiJVL9vdrq1xDzmTG4nZQTwDVs","Wczk4gdeoHgtmf4BDnD2fW9DYLtAM6ExQ7","WUr3x4bBnjvvHaXBGfhb61pvaRvaPYKEns","WTHoznNNexRbGespeBkU6hdNVTpaCWSW4g","WmzoTfmyWNGVVmWLV2FDs1YLLCqAVDwN8f","Wmx8pHXvrA4Vz8tke1V9sTUFmuAtu3jbeL","WXSVjzaDXJTmCirw8ZfZUXosi7K4WTgznC","WkFFj68hQ7RacPivihyT3nHYxQgaNPamhm","WUNVhWo9BnURN75S9E99UgZLaFeQnnfi2t","WWfKCKDEM6BDEVVcX3DJYjENMEYcrsXyay"]}, +{"isUsed":false,"words":"buddy fit real ecology chat warm tenant dry crack apple skin pudding nominee object oyster link approve blade ostrich wide acquire provide myself crew","addresses":["Wdrv4RrbU5tEAKsFHUfD2oTcDQD5mnJJDp","Wj27CAv6hGCUMC5TeojDjGbvhbv7Z8gppR","WaPLVa2VNARGoissWmide3fvykt4nvihZk","WbfRaLmZ6k6DrDwiPzNLqPrTdfcG5i2Uot","Wj8SMZ3nGmZXEKuN3Cq9MrZB31weNq7SDj","WguUdDY5DEyJcZSqhc26mCLAbGT5JbG43M","WhaN3S3p7sXTffTGZ6Qs3xzwreKFGT6NQE","WSGiGYWWPVYiKbi7EqqhdyRQFZJsN7onCu","WjJjUsD7v3wyi4TK1HJvhaHWcbQsFaRhRw","WT7gvPwRXaiGb8gSfZkYNMdjN3jiv5ghKb","WmJ3kpaYjMaFRF42X24waoLcV731GFTWJz","WgJ9a9R9RfnRNbA2ay4R2vyiamGzG9GhnL","WkixCBX9hs6S4A9FchRUXXty9TYTjDY7HC","WUQZcVUFxJqZ41MNpjz49oA2biUVP3KAfH","WkvE9x8QatD3PiBxapETQxkXeeTT381Guo","WTVv4Kn4Fs8aZuo9irLZySF9Gh4WmKq2LY","WhMuhwyybFQ5K8oHRDkAJsD48bsDMD3wLL","WktUNnvp23jpjYq2EtN5txAGMjyijJeeG3","WkpckMtMhsXKg5uXBcQ17YkwSbttEwdsw3","WfnGvj86p4sqKo6ggswXNNun3kDFnSQj1D","WQiBb64pEcHdChyysAsz6SQAdLwn7Nc6Uf","We4cMa7MvWEiLVcqBPopdRoDFCRcBqsLTX"]}, +{"isUsed":false,"words":"lock silent best cash endorse salt road pupil prosper moral example online vessel upset pen muscle rate copper monster mind enough current this miracle","addresses":["WZGSziEsLEtkfydhBPX3T9vcu3ZYMFYHD2","WQ4nZvz48LTbPqHBMwGkLWZWbWinTd2EMy","WWZyYbqbKRWZjRzoo6T8wFQWkBZ7tumvfU","WcGFhu5VmXQVZy2a5QAzdTa2yTcxuPcgpM","Wak9vH9fhY3ZWFYx7H6aJoEQ7hREBP6cGh","WRcLyNjX3PemwUrqbkoBn8k5VbS9ESes1X","WbcyqV58F4BsFoYjuAWj2ttz82QQd812Lt","Wb85Dds1m7FtWNZkEMDBN6W4hezcZMFgja","WgcUboDaM6uTajot4pkxscChGWUTUTo74c","WTVZP7Nz8QifXHH3Xg546TtA6Vc1jqZ6jz","WUMtXrq59nnyuHmFBuQkrjhd92y9GYiyCA","WZK9wufj4xCZZbmYx62h2UbEzjQimNLJvq","WgSPpv31Z1KcKTpSDedpjzdFQMXeicfeo6","WiiBSjxnUSzZe55tyP3nW95ZiQrUoJRjCW","WbN8C1txu3CDUZpCVmoyeJRhAAX8sGENgZ","We7qgfoM4vC5sFCP5DLsh2gm3jusnTJnwU","WkFoMTspSDGsUgjnw7UJWVhfrpV1BUWK6Y","WRa8PcrkCATnUy9YT6mn9eEiWQEyuLuxxR","Wj9k2h8TV9TcdtwvHX7hqu5HRUsTgfD7AD","Wgsgva7A6K2hvk3WJRqjRKsHHhrDSdJpyf","WhFd1utXnZKVFLjE8K88BYdiGes5PPsQur","Wa6YsQBcRohYS8zqrTFYzHTVWr189W2Tdm"]}, +{"isUsed":false,"words":"economy cancel agent job violin next pulse renew fitness battle flush salon often prefer mutual melody few advance before across naive silent lend valve","addresses":["WjhanHazNUPyaxAws3GwMUDmgiXzV8XQFp","WmdBcNsCu5RaUDCu2X5F1vHrhQ1BgPzyhP","WYY5DZxza58M33jFs5AqB7Y2Gj6CdFadJ9","WX25j7sbeAdDffCLRsrtDRwpY3yPsw37hH","WUa66duket1pyZG19j1nByqsU6EpW3YezU","WfjKwxY9QShhKAhhvc9DaRuk2rEXQ3hwkd","WYQypEWp1Y7x2GoaAsPxXvkxuMxfVJd9Cc","WiEQcairARAGMTrK8SMfTmvmhxGPSFrEvA","Wmm9m6qs4WTotBuRvSY6jvvZaSksbJiYHY","WYbkyaF6LJhnTN68feLQey1tTJ5ozr18g9","WaQvGhXj2zDp1AiodXTGf8XS2UvV24pf1e","WhaqZX7D3oBCc9V46aNDDxBa7ykKUyfn9A","Wa1bu5eVgVYJhxgWVi7uThVf8d1FcQyfEy","Wiun4wX6gm2EJGR8mGNZ4EbMZESMigmip1","WhmztCe8M5UuVexusYLbxHMi4uVMXDBP57","WV3rLUUM7Z5C9FetsUCbob6CE1CkojhqEg","WhAXd9i5FoEaByLDfyJ6aexPNmsxTtyaso","WkxKvb8RDiXiAkxLF81JNM9Eih5n1CrZZR","WbY5SB8wp3bPLm574UDriWZWD18vphnRR8","Wi1adKEyJqHZz9C3MmTiq1y9qEFJrFaQMP","WRsaV1fS5sDettQvMo4VohrnpbzyNbxz9a","WmNvFNrE77FUCEpn6r9SWd5RCexZoNSR9Y"]}, +{"isUsed":false,"words":"distance draft transfer flag ensure zoo arch leg business cereal tornado code faint oven domain protect zone fossil sustain turtle attract peace hospital silent","addresses":["WV4f9G1Khqp7RjhHMmryszJZYr5Yjy28tB","WhYPTkhmhhhGL3fniiSwvr69hVPkXN2Qxk","Wc7KTP59TvuhqkJKhRKsMVXYoGRFdcfj2o","WeTG49LDJzTfKQswWgSUk4hPH3NynLobYc","WcXY7pAhHGVrb4PdNQAvEa93r2pZW6QaZn","WPL5gj4EnyyZ5nGR71Cb5HwwpDeRfQ8J9T","WbXJMbHo6EB6cuFRkS6hWVv3akXN2afJdk","WZp9yXVNFPVANtqqzy3QVboeAU3eqcpMnN","WXJB1ttEgKKbgFxAc23ERHCkf3Z6YsoSJE","WV2vFuaFu3BR41GLxoQrBDgyVFyaVkLWzZ","WQmq31jFex9pptZVeBVAGdbBtL1r9hvTgx","WgUhCaX8ofsqh2ZAf3bMRqRZMjADYgBfhz","WaCatm7ma2jgEquSvNpQGqRWidqYsveuSX","WenzPia515Cqt1i3vg8A3nJwm32EVzmvAu","WmbutXji3v51ZoQamjbfeAbxYyChJHtuZQ","Wf3of21AFyXVJ9SsmQEEg2dUSZxCVsDV72","WWiudaNTvEx87uDmHHpy2Fmb8vM4eiKwsc","WmoAkwKBuxrmNNAgbq6E8PaGkJxVWkUBvc","WcHqdw2tAZDhC9UJp3YH5YRtossXF1hnv9","WiJK65FAyQ2XRqFLxShawidRyaTzdc5SE4","WeHfs9k5kptvYgn7YdvFHHdN4C6UngEqJE","WdHbkTnv6t28ESvhZpcdisaTevVRYTQPdV"]}, +{"isUsed":false,"words":"system junk plate mountain baby lamp rough comic pill turtle february grow year mistake script beach injury example mystery enrich almost bleak penalty race","addresses":["WjCFwTCVgUZkxxKgqWonnqfjAg8PirDXuP","Wdbw1foLuG662xTVUiu3aDBDmpZWRphneg","Wkqg59YD1L1khofbtctfHuwDRcoywCrAug","WXYTxQV8CPdCtSUxGZW6YAQAJXeCGBc45C","WfYUyz3SBJpQzqku2zZ1KbyBqu6wL1tEkh","WX6Tbwnz3deqbPVNtw7LoDrTMjdU3knoHX","WZsc3dmn1nH7WzeZmss1VsyQ5gqDoTneRg","WXWTwRv8mYJASNfuvURU1g5eomAbyEyNhY","WguWnsAQ731foPJtFRMqcbfgBhjj5nXBq1","WVrbBicdfVtUSmegjHgj8gkDK3bMUsody8","WjaRrLrmEPYXBdNxPj3HmJTUrKozLYySjp","WYLUiQt5NQkB4McC2fTuGreSzxddEQHf3W","WgN9oZXryTWaP1o2tcS9purwVfmRhpbi3R","WbxnUGHGBwoPniMcPCMKBqcU2Vh3zaXF6n","WZewyPvaDSbvhaXP1A8CXTn4qAVr3stR2M","WRXnXwYoVeN9vKUkXW6s49JJab2XbyKQiG","WivkuwMHTZoedp5M4USnST5NQQTiJeRqTp","Wk5AwALmjmfybkLG4KHo7XnFbcKnTZSBML","WfwUUZvAVR7uZbr4JzG27uTiF1SeMydvjw","WeGDpwDGxoo5CE6WBBS67M2JafttirWAuu","WVs3QuXBRdBMF4ciKGfdwia2LaxYSdA8KE","WPCyURZ8PC2haXNWv6arpDZrsPonMSeR1B"]}, +{"isUsed":false,"words":"fragile rabbit stomach put quality dwarf vibrant cloth this scissors rare stumble dizzy north oven sibling want purchase staff smooth lyrics frame rent weasel","addresses":["WiKuKUR8qsGzWkccu3w1GphbrwHT79UiSk","WYMzQDk3TsgvLd58xEp5e9oTAtLb9mB69k","WcvVfBhF5ZPDYdk7enrMX162TM9QuERrvv","WRjPADcpvxznwnYLzarnQTCF8zvpk6AEvD","WV3CUevSaWqcCBBw9vnjtGu8adGRpY5ZrM","WUT1Yy8ykfMRCHGfr6TzBrggSDuWMocJX2","WTyWkai3R5xK9zd5CNHzMnyiyK6XCS1u5G","Wmk3PAVjVxudTxc4GD7GLeYuvnCPGBUrF2","WZVbBvEN6Yz6xnDSN1RmACp8yE8XzStq3B","WhuCFnRe6m9sVVGeuMBTsoGNbhmv8E3i2H","WdNSLPbBeHaWHNxyMbzYdwNEk7v5GGNfBz","WXp1ePcwqyLowS2WqXTZu4fUDVwXe9rYd5","WiAaet6gJrH1ehFjK8RaUwJTf9MQGUi2Gr","WbspfSBp9miemNZk394CL2i38XNGdHjV49","WP4fBwbf4tyEfC6wFip6benRgv4RLGntCs","WTLAStwe99r9GYFMiDWFsnqgeqj4ea3vuV","Wf6kfMFJx1HXNSmAjhJcATXmodMj1QtU8i","WQokXwyd5ESgWfMhkFxuc2fjkqbSUDAYk1","WQx6VmARPcKCyuqAjsoTiircgfuQ39sSCR","WRUGtf4sz39CMX8DNBiAa1Gg2n1DUAK4s8","WbtDYrMwTyGFufCSraQqrsqjqqXWgw52TW","WfqUTapLwDuhgvWFNmeiCgueT6ntqSurB3"]}, +{"isUsed":false,"words":"ancient network scrap grace sock genuine bundle subway only video army ski scorpion couch noise weasel neck rain cinnamon inspire disagree various forum soul","addresses":["WWEUZpYFwrFABc1GNPEt5NULir8YgRwPcB","WegwWjZ5S568PhhMmwcUht9xNzBeH1Dau3","WRLEg7M6PJGTRrnxQTyob9tf1s5qtNoMzu","WWi79jGKUmV84CDw3EbPdhAk15yZ57zgA3","WPvoSQywCw3qx8RgqrfLMgFkrVoUiqygfy","WYNA8BC7N1EnMngRhGJywwQa6G3ikqYnxH","Wi7aZCor4gGMd9W1hd8J1wCnjpw4b8EtDR","WUZWycRRNVLLsLXHWGvvxmtbK2AJTVu4sy","WRSDBwL33uuCCzGQpZ26ZvjerPHH6qZwNf","WmkDZeSVBd2P4P3b9ACuFVptWYzZYcR7oQ","WXAAX7WY8zWKUu4L83hx71aFFewJ41Ms5s","WSySxrhM6qjckwfbzDndkwL6AJgzAbe5DT","WXRSYzxzmqWYoWhChjRYRGWTFuQWgC2F2Q","WccMAYjZGshqL6JQQpHxHBMz4TEWfSB9BC","WdxeiUGFRrCQvLoumv41ZnTDpvjYdGAVs2","WaBv7pguDeUBZnZsjCq4RdTUfj4q27ZmsZ","WQQ4RxxtdV5zBH7xPDRE5pXDtkoPduFMvQ","WZJWYksJWfwtxdz9d4XrKTDErMhbpDjQrg","WhHccTAFBD4UjT38HQndsHTXQgDkPSPdkX","WTuhVYPLK9GrWqc55d4wpJr7DiwTqdKcme","Wd7Mu3C6QhD3TBSSeU6vpQJNvdeFrEt2gp","WiynSmG1wkpLFD5uxPCcgqH8UcLrcc44cL"]}, +{"isUsed":false,"words":"brick enroll level tortoise today gloom jump stone clay almost snap clump saddle embark gas term holiday pulse melody roof already hard glimpse avocado","addresses":["WjzS1WEtXkxEKMRThQ9t2PhgeZj6FKiZd1","WUcpGwXVFG5tYiRXQESSCfj7sErJQGuVej","WWf5MVHsEV2yCBND2o7wk5jvr6GqH6ZJkD","WmhgMq4NSojhjZs5XX7CpkS3YGVh1nHm4N","WavkRGjgyehxHaixbkp8MZmYWoy18EGQGw","WTXnJ1fAZPaGefPaDv49Uy2BzyN8Qryudq","WPNquUsqGbX7p3HcFN52o6xU84XLNgKcac","WWtM4qwvov1ucHxnMKrJ4XibfxgYAPYw5B","WYpUkpLh3LKbyuePTzcijdYCD3RLUFCGcG","WdVVoNigzW2gkeZg3mgx3xdcCfS3dSCs8E","Wjm8RmDUwFMtu8LEHuYMFb2mn9QcKQQVQ1","WUZgCBaMo4qum6ojo9eq6gv818YA7wtd1B","WVpoTLQm3X4jHy1DFnqcuTBEGDR9keq2qQ","WQ3jL8MumKjiwUSmNJFgVoUtXzj5iCPhBW","WSEDaXK36iABHCg9LdFhEkJdSFwFdid75u","WYfiVAsDJGJx8nHGTgoNNxHEB7tzCuXGZ2","Wfc6BUhxgFfsVtXBHb4TqQvEAzJRdZJDdn","WiTGYnts42YA9eVSMYsYAresv2G1oJWRue","WWHe7Ge7t8j5jSVVLJFe5UF6acn8bbG7Cv","WeK6c7nRxFSpkh7n4eoF9NBZsNpPFkD1LU","WfA9mkTcAxf9ciYS83H4YBAMZzFp6uREw2","WcXpNyi8mbJViEw2d2SAMJjSXv444MsLe8"]}, +{"isUsed":false,"words":"demise diamond hamster canyon evolve clever call ostrich early merry love clutch amateur hundred oven shoe minute unable shine quiz famous nurse leave since","addresses":["WkhahiY85LBWVy9o3c5aRmUETCSqJPk6tH","WUCUHSUu4Z98tg6edQhr5BYdFpXvsQZLUV","WmngBR8kSzJdQHN2z6RyGpnLk4dMuYApgz","WckkJ32iBP7etXt42TUgASBSafGr9LKWMJ","Wa68NkxjuGawxoUdmBKgNYkwoA9PkaKZBN","WfpJoKXa46RTLSW2BFgy6pVrG7N9QuRorE","WR3pgzUNSEfpXpXQu7a6eEbn1URpd1hoUe","WNhsg69aPZTCravkqmbLDv93qGAiew5aAP","WXvUvX5rnqfGv7Jq1ksquyLXtdbvpuG83M","WSUxsY77S7hTSa2Ru4ETQJVz87y94PivL6","WaM7wNsug5Mb5Xknw8B91CHEW6aojswsQG","WdHgB6D6d8SFFZxpQUVv2zsuZEVvEBnnKd","WYWh9k9WNiKD57a3FenQcxgwM1GKi8Msvu","WWCKvHBdtEhtHiLci9NqgBoBZX8v2mADNd","WPfYVgHuLrPK5HhWbmXqJxMUh2gR5suHBV","WWfgroqLimok6NThH9Zavs435BPg9aW5Fq","WY58hLixdrb8chHeRRZmcRxSAXtGeusUZp","WdLu1XFHRn7ucS599mPZBRueMgCe3yXYFh","WST8rTUkvXiFGdnU2chphZMZDpbVmcZbaT","WdAXvGs3Vo4r4n5du5Xy8faRMNSVVpCYhv","WTRs6RF21MjqH2SsjBr8qsNVfTNZ7s2Ydg","WUaqyz2GBGo8tMK9Bmy9NzJw6W2n4eTbgz"]}, +{"isUsed":false,"words":"biology warfare napkin pipe soccer build dilemma mean assault priority client child brother second pave unveil faith protect iron uncle street pudding borrow skate","addresses":["WcXr8tiiZVwDeg5LyY5nVcPfZ357rcNB8y","WQS2YNn6KdQ5UGaQkwp4HVzNXZEPArDgDa","WjrC9euxw2wHVrkwtkADd9RVjyG19BpLwJ","WP8QgELV9pmvgfcJJVjP3FHQHhhAPz3ZrT","WkJxatzBENjb69X8dmaWhM41aNmyTYgskh","WX1yjhYXPQrcd7vCedEiV13AYHKdtfYWLX","WgofkbfkmjwcSg8XSSuemMrUDMcfPVzsNY","WXC5BKkB5hghpyNURunLd1XhyDpNcBAkNv","WP2kC7u4VVH2aPgp9fgsvraS4EJrqjToaK","WjjB57Rtk1VeFou6dqxt9He7iR1WFeMqer","WmcpEWKHXGBWyo1j5eqahc2r3rfgEcTMyJ","WVyjpNxR58cojEFRBAG2kPyjC3qzQH7Gyv","WeQc9aRcPkxM96ZSqueiLLTmhGLBEGaPiS","WjoAJkA5AYzMqenvr6f9CE7v8CHwCjLUqa","WiJqVMQb8MEs5sYrV6rFU3mStu23iiEe9P","WeBaYRYKA41DfQBRdujbu1sjrhmr2phd31","WgMBcBbqvqrVjCaxztBxbD5EbBZbsq3dhk","WjyidJLn2AJm64dWjd76ZnhSv2u1e33XLz","WQWZgDu8HayjCRTGtveBnwLM9SYtdGZSmy","WjVyiCXgPxmqJY64bbjqc68kFokwiKHSMz","WbmAWyz3wyUdKRnqLDotfQ8WJGfJZCY2SR","WQU2CmGq5VLHWrur3H3VToiSdVf643YDMK"]}, +{"isUsed":false,"words":"old earth head fiscal domain exile plug deal brush exercise label water warm adjust age kit mirror mobile clock grape duck update stone morning","addresses":["WgUoqewNduRHKZRMwyEVsSDcEbntZLMimk","WeyaZ1iEpFYME5QonQbdRiaPz5ZYxe4hnj","WVTVyTJFPTdzZfTMZLRayyeo6mbRxzQfQq","WfKNBPuMQ5YgoyGuHZxZao8b9TVydiSsv5","WkaStM8DtAawpDC5QoEgDEZsAfMhF5Kcu1","WRYaXdAo2E54Lc6fHztt5vrFS8mZEpvb13","WgoNyviXyPBMS6EyggafJnCSXHgQvM4CUJ","WURxXjyDozDXy67eW1VgbFy4aM9pBSfEaX","WTyQJKRNegkq8D9R7gpxkSZ9gCHreJBksE","WWGpvP6ZT2qFotb8Jio5SsG7iEV9TV8TQ6","WYtZW4dP3z3aBDgxEwWN6cKEZf2onzg4h2","WmdwP1Dqiy2VaLwcwNmVWJ2vpoENcLWab6","WWU4icfFWFwp6Tg3eEYswMFjznt2cmo6E5","WicQjeQBGyrgeJ3hKTizVCXNDWgV8u5a69","WakADoqTv4SZc7VsbvET8LLaGet3ak33FK","WeQE1Fr9xMUP9eqcTCbotayagtT7JARh4J","WSok1v8WNhs6afXy5DDvEUu8AY4P4UiuRX","WVbB7L4YKy41rZT1tw2srcyGUgLjFfohS3","WXBMKXyK3Hq8PeXd2hH2VPainD7zgq63ka","WbNYZMDiV9ZPWdwi7zBcnG7fbU79e6tQ21","WZjDNFLdQgpS7pT8DrP3uv3ybVTqakPFYx","WcuuGsz27LjvUJqW5kdVg5WVm9u2t3PszA"]}, +{"isUsed":false,"words":"trim matrix spring picture bike wreck off prefer crawl horror myth best enemy afraid jacket winner actor fantasy guard host thrive rather exact emotion","addresses":["WRGAqGobkSrN3hNUKn6JXHabZFb9NTaV4R","WQgS6nGwTUCBmu2bynkeS5msSaMTkrhXVG","Wg864XXqQmYXjNnT64Viukgq5pUg9ztDwx","WfNkD1xFjZgVoLo5cwC1WU9JvciUqJfpdj","WiWE3AtdfdWD8JAdykaxWSBPFKYVHxr3Fk","WduXSqEdpkxEbL6ks9qDT9xsXSi7aRL3TA","Wg6nD2AT7H5RroH3JnEJafunDvPYkNNvt7","WQeXUtSr4tzZaSGjuBk6hv5kp7L88aSZkV","WRCRBfsRZzsVzxdYgoQKm9U2okuYCB97AH","WY6DqbjAB9w1yHAvGBDkCnifRfPDSxsKGu","Wjaoig745uo1NS25NYmdYKbRpYisva1v8d","WbdANrA9HzsUDqfFSpEGtU4YGwWFgWs5cU","WcT1nUoioGPAsnnesNvh9ihyBPhXsap9JW","WZ3M2qWs8JiDXZ5V8bereFHztcKyYsK7iG","WVM446Gbp1fUxNFVQjkQFPkTA4ftGadAi5","WULksQBWwRpW1QHA3wjKtqWaA7198a9W4p","WQx5qMgBwW1EwBxx7ECy6KsTaum9FQMAAw","WXJAD2PEHDtHhJceqrF2vbkJKSgGydrzbb","WVThjUiUaY1piDeF5X73eZv2R2TZUgzYeM","Wimknif8EN1tYcG4Jw9u4fjLfDKvZDs6Sn","WhJMkATrcqJLzMctzogdpax5a22JNZoKK4","WjguC36GU92N4zsrMmKvUQGcTFEGseeGAp"]}, +{"isUsed":false,"words":"scene artefact brown april muffin defense skull speed dentist cluster flavor lens parrot sting grunt chapter focus gloom delay aim letter reveal apart weapon","addresses":["Wgd7vf2hc8UQeLgGWiXTLbwsRiiTJD3fmc","WWfG84UE6kCKc5vePiUkHvxEj4APLY4rbY","WQ4uPhZib1RgpQvXkyvH1SfyE1vVs8VVmW","WjGeWfDoDjSduU17dqCMjwugELSpM71aTW","Wiw3m91tRwHDZCNe2JrbUnq4hskwbwmuDT","WmeySR3wxQuaVJYDsaKsfV9Kk5T5vhpaH3","WZk4irdKaTsC2DjTt42w8rPs51LDbWfnMK","WYWZWWZemMdRH1hDx84WaMVYxqQcLmpBDd","WcxpUgHUXQUtUtfQntnPn3Qvc4ETLATAiN","WZMkivpPtkxu9TtvGRdrZYZFxmNAnJgA91","WawKek2idNsGdjFM1ahT2XA5RVGFmj3teS","Wjwidy5xMrLxH57BiST8DzNtPq4ooHogor","WP4uwfkPnvJCf4kLaNRpPBHEqvGxuycAb3","WbjLZvhNTKjWvctssE6HWA66YnFACVNZC7","WYCoFBiJFYaXwv36T3vU2WetktP5ShjWAC","WUTyrNbDhKftPW5LF2GPRoZHNQ72JsLqua","WPqXowufaV8DW8fkJzW87bcwmQmvkvF8ZJ","WhMVDazxYTsUKhAkvgtxyatEjiKvF6Ucrg","WbzSgAyHNvYiQbTMCuBqpNrHkMfzKwZcb8","WjhSfsKFZ9p9poJ3589cF61tPvkPMnnPh7","WY2PFZtax8RztGK41GoqqeRgi5KutxHtuJ","WQxKPQFiB6J61h5xjJDUPQ85UGYedJidLk"]}, +{"isUsed":false,"words":"series fat weekend brush dove merit injury total foil catalog ticket load ladder render include useful parrot fog because crane sort betray dose future","addresses":["WgfHsQFn8scWEVyqGfxkLQotnyLFQKSaMn","WSAsn47PqjJnMkoD8nARtewBZzUPT8wA4g","Wf7Tf8g9oAShWHhqHsCdRobXsxYAAsu6A5","WYMhsgdEJVtSL93FpWgrLZroVRMtEpLpvG","WTmRRisS4S6rE3PUPuCXQTi1MzvZqdDCCf","WajbnsMjXm5ZG8QFizRsjZiRR9YCguKYdN","WVPf2AuSvZXtkcavXjrxr8jfSR2AiUHukS","WinSvvC86apLh1yhKxFQV7Fkk6QFfK2CaT","WVgiGftPmuqua4D9PB6ziNcYmmY3yzE212","WfaRBzwrzLLfcxBC9xU5GPNCWCp8LSXvz2","WXSmM2T4aa9gEo7wyRKkypdztE6RFzQdMx","Wb7hHunmqo4rc1Td3VDLSGLf4dQYXG9SKj","WSVeMun8BSqaDjKFnxFwEzNsAJxtdfgxXw","WP9x3WXtFXaXEMRvfvfEoiPxwDRAewtJPC","WXDEJWA9X2QKAXzNGt7rVFuUvfGwKkZ6By","WmMgLaCwzygTCxo1p6AvkfDHD4tqv6gybH","WWeTBcDNKMPmpySBz1ediSU361vTz72RMB","WcQguG4oHJAnSD28R2x8x7cgzu8LrFLY86","WVLibx4jZhYQrVsx75WGiBR3bAy1PocacZ","WidE4ETxSeWqaeLTvhdBhm4jVAoWGyT9CW","WU6xjB3KzNbSbLxC2hwwwQWJPEaSna4zYh","WPeGiQRexGRLMswEmSAojRkh5XffrXST21"]}, +{"isUsed":false,"words":"topple lucky until sheriff squirrel forum odor heart injury cloud ask purpose bulk venue fall devote scorpion illegal crop speak trim together silk mushroom","addresses":["WjwgyioYbKAEDJ8UZReP978k8wGkdGGpg1","WWwr9BZ9CE1F1Z2bnoMPxiH8uUdVYPC667","WQQ6eEcY8AYstmYWVDfUN2tDnEDQo2PJwK","WjpCVHj5ggNBFbeSjZuPnjRrrcs5psaQss","WQ9haM4v61Yn9RZKXCEKjFyj26vWLjC4b7","WaWrhCyxXx72YsLD9kEteT6nJHn8Ehwya7","WmuhTVx8ZYDWNg8s5z32pUvXi2oM97FTk5","WSXhpJJ4tQVyEpeXP2WeXih4siHir1fsd7","WivXAdu6R1vFZAc98SS7JqKNsRGVRJTpGc","WZ1atUhjPiL28NGhJtD9WtnjzNBuS7wueT","Whja82Bd2WD9BaqSywVvHMwJGzfPCzdJWL","WktoiUop9gUPZ5DExRqMHFGAsDYY9V7opA","Wkg7vTg9NAKtQQoo4cD3torENF9H6iDVC5","WmEhiQfLsHJUYayPmAEJb3LPBESpqtD92W","WQ3FN2wyug6qTyuLPxkJxPh91HopUpphsW","WcKy9S7Y8HkYN8MfnEp8pw7hwxpYkvJ7tY","WVfxP3gGXaJvTtSQZu1d6nFFgGhzPEh59r","WaLRKUp3cw1N1aELuqpLuqtobJAVMBEfHL","WedWSYQoWeoFqvHz84ZqdPWievBphP99gg","WfWhvPbUR3QAGDfxxtopeYo1qD4yebpPmp","WTXyoHcYMXcywSwt98RCHL6rNrcoyZNjuL","WcfoeYcs7MAvSP7xZ48EGqSpoaxEYXS4bw"]}, +{"isUsed":false,"words":"object fame produce yellow ethics chunk bike peanut equip need stove hover gather emotion globe ginger depart ordinary creek worry fee around shift flip","addresses":["WVzzSHFeZ8YkBKfHXYCB53xN1Ap4p5j4ak","WSK24iMPbkGi6HPiFcmgp9f3SFFogqXk8j","WYSCsHTM3wr8sc6WYt9VxQzEGomsWK7XaM","WSXEc6v2j1qVr4Kd7STfFLVcCLTaNqJqsE","WVrzjV8TjQnhGyWS34XR19hhqaVcDJL3QF","Wd53eTkK83WeYzMAET86b7Ck2fEQbWiTYs","Wiy1snCsq16zT5HWEexAvZdkFn9ab78PhS","Wb2LpkatPHnh1t2G65EphhistBk7WXZicP","WVep8N8L4TKCFj6B1HBynXtnDBRgapxNpv","WdwzM1VCyD82yptyNpyvocWkKgHCXtG6Kh","WefszLz18sGnGdEzkc4qMVQC46spZ8hDrs","Wgj96NN6g5rVXb9rY4jmUV7d6uQjUekyiY","WQPqjt9EkxG46HJdSngP99qmoFdMsCP1Bz","WVUKkfb9apPnsVL13yrXd2TzMh5Ku8Cc9B","WRCJh67qDsWyPyDdosL66NgYpR8qaSsfwR","WQK8VyHYa6YGHAzahqQMNMsAge2SadnrJZ","WkotpCjE5LodDsav2m7hc8ocFc53GDN5ff","Wje8MCPWgDzb2PuvXLJBR7nCNq5CK3iFEa","WS414XKNBqVogWaCpkJcgLVb3uaCk9M3EC","WkKwD4a8g9Y93yeUvHtfwWrAZDAEKCmKxU","WRH1cDjcXHgEfj8aBpmjruRpGH7P9HcEbp","WkmoV1ofjBKW2vg9okuLRRd2AsEbfEysN4"]}, +{"isUsed":false,"words":"fan canal ketchup erase lift siren quantum motor talk only hat clinic voyage make page noise rhythm pony jar evoke autumn damage color coconut","addresses":["WYoHxozmmFa4wejvJLz3qY3AhBSAw7jk8W","WPeanft28CEtys3kG5H4GdJiCydKMUyNkB","We6qRuKDVUYCrPwP8jrcjfZ2TtEna1154Z","WmPdWj192mJDA4hAc9H5rJ72aM7xFriFEj","WTJk8jZE1vNXDenhY9HADrTU4UHiCukne5","WkP9rBZTLoRt4M2CVDtfmJfhguPYn55djX","Waa9m274K32jjCnGjRHZr7pzBiZGSxSQJz","WQM5JG2AHKhwoCDimsuBMCfqxrtQ9QddFX","WjwPxiwPeuG7CMPFL8iYhVmiSvVEq5Hw3P","WPTvqK6aFZizovEuAuPLr7gvj9f5V88Rkt","WcmkzeZK8jkvaJjNyp6Pjdu7d8CG6PefET","WZjjXPf1jrmBHBM1dnwL51TpKTTLSz1Vkk","WSooLMVWVHZyforACwZ5F5knfWC4G7V8yY","WVfkiZRXBftaDgYR2gqFyiLDgcwkxHvLrU","WhFgH4YU8EQgHJbVXmDheuiyB5e7Bm9C16","WQbxsDEAsRxiUPE2eAAEZJMix8kGcs5Vt6","WPeKecevFBNmPySNyTz27FRuoDPCC9BUme","WdVdK38Fczz18uLVHfyGcbDWPGynVxbCQA","WSKmVzpdRCvxkGBDLKpAURJuWQYrgmisXh","WRAXhxh3uFUboz7jZfZXLj2XbXqrbhcgr5","WTPyXk4UgQBr3YzHSSH5PYXzpnCDyBKaJh","WjMDQmzZXeMPTqCDuaVaugDp9ZjKNUcMMR"]}, +{"isUsed":false,"words":"lawn below cupboard venue cup main recycle card safe safe essence rubber thing rigid dirt hockey option secret mean together toast crystal foster require","addresses":["WjnHZBAdu9F1rysNcimsfkxnCQLYs46pW8","WYc7K8jiVYVFJTVDLt2qZECLnZMJtMxHpm","WWvqkhZFAkukvUTMvnGkMZWcuzarnLmApk","WXupfFGmnZYwE63ArW5pGFMRTikuPvzCp4","WRE65TrjF5LjXcTAJVJtFrwh5uA7DAenVK","Wm4aSVW5jNeN2CHmPPc53BesDvhC2LDrqQ","We6vNXEhDQhVu3PsVtSi1cC8PH5YbCod98","Wecn2AdHE1czM4uUWjF8YMzhiMSMTwbavL","Wj8ukfz1EKpnRPzASR2hLGSeD1X987wUoT","WmvQiXQ68wHXy8XKVKn2svk8dQ3jhF2KsX","WhGeEKFt5gRkVpcmCjTmMjv5cMniuETwFp","WPb1YqEUZZns3LuVHhejMmg5ANGDrTKXoz","WjpVcPQ3H9SsgBnAioYpCwKXxmZ2orBzjn","WQZAQSje1xCQLiwMQicXx22v5TWtXCQWAs","WSK5EminpAxah1JN23iKRzbrdbfuh9bYSy","WVvxM2zNSygDgrs6d4A4TC7kGZSyb6Jy5D","WRv7gxKWC8dtB22BtysB4cWoXHMRL9iKXK","WRiHXCSeMe5uwZM9WhyRQ9FPfJzNqzNvSu","WgJ45aVowvn7DumaraVv35E4nK3iQuHu3S","WXEW3seAUW9r3swBKSZFRftvKQzjrW5hUq","WQ9M5quWaZraTnscrPz9TdrqBHdjaFcYp5","WSHB9NciePzUsdHLdpcj2fnptn9hBumAyS"]}, +{"isUsed":false,"words":"ginger assault wink later pepper harvest artwork sock inquiry service grain toast miracle purity tide comic coin myth memory melody whisper sight bullet cricket","addresses":["WNkMTNM6SWaUGJaBNp6p5nDfvPTCZWTMcK","WhQCEtGadAVF3huMnaTHpyRUWs8b1YPtwY","WaxC2z3vLiC8HghfUPYNMouFsdNXS4Vjce","WZWqSHjw79L8duFHH3Uem65Li7YQgFZZ9N","WUSCvBSGHzS4HZv7TGrEoo3H9QcghiFzaC","WZT9kayzB83mWrnmA8yNKR84foAuj2ntn2","WQSxghGmEKRRuGvzoyTALoKDx94byBz4HQ","WXe6CYtAAfcyToeCJ8c5h1s5dpLQE5p2Hj","WmA4RfbaFjZTHEDxSgKaUBi6QDNStypbyt","WhBeiX3brXjkHcwHguJz3QpHf84d2dnTpX","WQwMbGxfZzvxdJyrbztk68nCVjwQde1Liz","WjG9n4SxAxpQhDt2QDZDptvcoE7hKwZdLu","Wa8mnxYzA1PzoQx4juKe5uY6HDkunjKS74","WXxamJTLSaApFquLzqMDj7USjEneVHy2Ei","Waw4X2bU22tUPtUX4dz8Jsq7eHwBY8bHwF","WWVhdHjo9U9TkqkAcbwYoz5NHdfHXCkTN9","WPunzkcvDm1JowptMuBqrGwzdkPrdHBHfG","WiZrjQ2pwJaNHqc4ULvmo4BwBP7kPdz3G8","WhVYLwe1LMDJkfTftQ2ncTSmob773gZk1w","Wgn9j2YcE17snqsaWjLhKUoJNDFBr549UD","WSdTUVovSjZJWppXPyAp68dfaT99ZbytGh","WXscZncEMB2apgFEZxawFgLuYhrmFThx5G"]}, +{"isUsed":false,"words":"fox deal bulb melt lottery joy educate fiber way order flash arctic clump tackle poem bomb glove barrel crime core carry bless divorce danger","addresses":["Wcc3QGocJGVD1WdpymLbzZ1HNkpcCWRaVt","WebULE4Xwybmnh28PGg4naCUUuZaD12BQC","Whm1jjGefjU7r4RQhECpTnhv3THqBJ6CDg","WVbojgXugdyUMXxkd5DDBDD9wqVUDuojz3","WZQsdtFTK6Y9UEQaFfsYxgkVkcbfjhJrn7","WUCDgyQ56LXRaohkmXQR9iACwRf27Z9siQ","WjjMDz6xyr9Ve9NjQVz3djcu3UDDsoNbKf","WWEzYfne5wU3QqhwiDs2rYji9EjFfkK6NP","WjSofZmuQpf7jwBabZZUGFrUCbAaABoGFB","WX3iyx6MBo9FGrVWzdFjCpaZnYA1qDrDrY","WaP3YHiQ7y54gc4k7ZwqMLZ8V23xVJHK44","WevZ1Y22nJzf5YuBc4JoLQ62aDhAacFb6m","WYPgWyaWHRZdU8YUJxyFaZbEjSwAsCrYVX","WT3gtrSa76xg2z8qrqDQp3JxGwZ89Nn2AY","WWRLb8xoTGupufSoqPKWk2nBM8MmkBqb6v","WRKUnPzN7C8jvMtBAVemPxJwD5rmDXXqbP","WmCgFEXwNuDehH7pyGj42WLfDBya1CBJ7x","WkQieRG7GJVn3H5bm4S29RpzKbPaX6kYNn","Wa4vE2EQQ9GqmcECUZNwfKJoz3J7HDTaze","Wjt7233Q6gRy8eGFK7qAnAdWDZcmZo9CPw","WiKdLxKqYBMxW9izuhiTXJZjYkLidEeaiL","WQPwy2PtHMdkH39dRCeHkw9iWevAzYPZyP"]}, +{"isUsed":false,"words":"blind curious lounge bitter inspire wild food glide confirm embark mobile roof cute window surge twin space canoe truth utility kit dawn confirm title","addresses":["WUhUKRsryoc4W6nf3iNHLa2tJ8XKJsmszc","WmYAL2XD6zBkzGQyPrutzYfP6j8qHqtb8S","WdgZGCw47wGJLxmGffVBR7pgcEbDW1C3HF","WR6nXArMWwyFDomNS4YsHbFfaiEzGNPJ1X","WPnhcPJTe3FdqTutSKwFdT2Tt3NZY8RozQ","WewuA238Ln5ZW1qTwmjyZQWZNTyup1tViC","Wi4HgXYuojCoL3enW4mHbU5gU5WGckoM2H","WksRsvWzqgGMK2n6XxahtmSerDBP99ri3x","WcgSBdCM8dcPscUuVBvTcWaYkwxScwYcNg","WPj5eAZpXTmV6ZuqUrQrC1mGKdzFrz3yKk","WNku5B98EP6fvdKkgpPrE2SS7biRPMwqLh","WmKPVcJiCWXxgiscTGHbZMW2faF7Z9rChV","Wgn1FwvjpeBWTdLhHZzvFUR5frQJdDJyE4","WQQQ988GbFEU1YXpDXU72yv2cnKeHZoyWP","WiRHg8EidspvkrodmHAm2UbiFrwVgbXnUk","WSvzGh32dhxrmbWLqmQ3Jzm5EpmpAx7q9Z","WPPhh2Y9hMDQvjM7g3jddnbsRBKtsQW2ej","WbwoE3mYf9vGcTxGFwQj9rP4er2AtJtMBA","WeXhd2mUNisswJXQURyu3zSzdeEBu9KRkS","Wi21oHHQBECB9LoYNBrXEJBDrc6gEgE6xy","WhnhUnuZvqUXTXngu2jot187DydqQMSU6u","WPa438chSJUKpyZxgndrXoUM78nz7QVAEW"]}, +{"isUsed":false,"words":"coin finger flip cinnamon evidence hawk industry elbow there critic hybrid stay small guard artefact exotic depart alien clay web hope legend tonight topple","addresses":["WPz21rAQNoyDqAY8rUSUsuKbmseyQnFani","WaQTXSsRLqWyGToFYWq6nrffoC2cZjHGb6","WiHbcqSygYeseBsLMSqLXcoqMX7sGMc13y","WcNoc1jAJG4Eybv94ybY7Nkym5M8WGDPbM","WYLFLJZxyDZvP5Buqa7diSZHgRWrHpAJ6c","WZo7SinGENG31AJrwHzvLrbmmVqjJNRAye","WkCHhHH4QQMM4yoTwGMS1hybzzTESehDme","WYNamd29J23ncjLCvPN1qMZz42oHANY1nf","WWHaf9djRioa6HCP1UXA3FMBrvdxGHjfp8","WWzuEiBCTMuDWaWkk61VKS5SZnyFN3FNKS","WbKNygyqEwnbqCak2fu9AbSSiYC6RTEev8","Wmu2PKubVYApiMACLDQ9yLmHiPuFREPvkm","Wj9w51Hdne1TFXZktWp5jqVkuKtFZN9tCk","WWeF1KJmDMnZyBHmK2YkYHmVT4KBJsSHro","WcGsviuX6vBcCePCZd2xakipQorENHAhA2","WQo9S3YCjgkACZnfxm53UBhcw8uUCL1Pyj","WfmuEeJF16iohjtLKEQyN9KEaXbS3CqJaa","Wc3cyqj2CXu3dKRobRuwewx175RQs38Age","WXp2MvMLiLsDBL7zmSe4DZcGtHCw71o3uL","WVctMQr8T7pvwMQGqTDZWyxdNTL14RpyE9","Wja4KQeDUrTB2z5DCBXu4Srzpf5DEQ1BQj","WXsLqLsJEe7sQ2XsXB62vbGvzK2umNfHQb"]}, +{"isUsed":false,"words":"flee record circle spin unhappy side clock fragile warfare section leg bronze bacon confirm lonely art safe install embody embody job weather dismiss enable","addresses":["WPLyXVj4fvWqeEhrcQjtGuw2C9qJyvrM5x","WQGr3oSczt1bPfmeTyfdWCC1WRM1Yvmhqd","Wc59xXp4iADtbcCWp4mZzumKK1usUfQTa5","WQ35wYdgH87o1TBav89WKSmcksZDDhZw6L","WTamhJ7qeKTmyipcRGegF8gaoVkttD6HZU","WeVp5PjZw2gM3V6pHc7NAzQwFsRaSwMVbo","WfaQFyV5kgBie7bqcBiJjzFFdywJvpTirC","WjMBD5fSWevRasrGymVzsD1qExGUYy2TUj","WeYYEqYSwhFTBt41ZGoNoPXA529MR1yQyM","WmNW4LSxUPHxPACkuvk3CtEmeM1PkUvBXz","WYP46dP88TEUPtn67vkS9viaS66FZ6QNWk","Wh2Ro6Vq5oqZ9AuveAhKRazoXtYF2wJVty","WRugrHMSgCGTU3mbknap88eFcRYWXZnAY6","Wi9RdVxqVzvq4ZHtMWyeGuACUXK9pJpqYR","WmK57ZxvMBmWnTeVbrJmCzaNYGfVk9bxuk","WQA5QBJmRDo3iZwEHTPsrt5JgdXE4eFhNH","WimDvTVxEwuL5k33WcRhaZTJHMVRcJqf84","WmsMyXVbuQ8UQ1WgVv3eLi8X3qrSCCf9g1","WQCTvVP8LujdG3PBCmXquY6NEC2zz2s9KR","WWbR3pCXn41S65qYVjACNG74pXW1eD3H2r","WkNCDSFGRhhk6Ep7PdqrqVkBkPpgc54Q9P","WQZ1teuktLVCy1NHDbv4n1AoEVR1kPQ3wU"]}, +{"isUsed":false,"words":"flame visit dinner gold stable physical travel magnet eager lucky legend embrace air excess shed sand sleep foot rescue eyebrow improve plastic possible vehicle","addresses":["WeyF4ZMfwDF9QdsQ8W9ukQNSVrC4VMiCVZ","WQbHqNEepfzhVKx7EjZA4kwAiMU3h552Nw","WiyNPNqx89HpstZH2rhZBqZqagbo73UBrB","WcK5L3J4cL7BUAgx1LuKb2YHmEZqXNU3bW","WWjF488HrHzfbQjQvVmGq6UWUk7uxhxWbA","WaiWwamtKM7ZV32LHHsb5bnzjmotVP83TT","WRZg2AjufJeJ2mXk3J3yrr7K9GHBj8LXop","WNwgntE6LvE8tCKXwQzKmJ1E8mYerwrVF7","WhLaqmez2BixT1QEzqH6JxvzQfR57ockxt","WkHgY1qgGWxjZpQPureBhfD3m2FLDM1fGk","WgAMwW4YRjRtV7YR54JNhVzxFKYqrz7C7c","WQAira1seRGpNofBRNVYmXBw37S4kTRgob","WTUuCXn6F3WTQ6mXJJXYpFiZd932cKeTzy","Wjgeksp1vF8CqRKizooMpeFVyTEBsV6ydD","WZ99yZokaW9bAEEwZcscUnXp5Fi1iEzBQd","WkE9u97LCL4fd7DH3aRXZNBFsoQ63VsgVj","Wd6sZCsLs9rxzXURS1nBqk5KACRJDrp7PK","WZ5QYoj7zUtAmwYRUNw3WQDZs5PnTSGS6d","WYK4Q1RDRkGdGzR1E4fAz5cEJNd4fj7SDa","WZRZxbDMktFGyXkK3eCDtdt4jYdGkbyk4L","WbxJ3WKgvFxNt4PdJgVgNsBKdrTVS7WMub","Wf4drWXBKBDvjv4HK5Dk4oNu13Mw22XiaC"]}, +{"isUsed":false,"words":"farm master wear decorate wool abandon post maze stage finger flock fiber desk pass notable good amused humble globe toward picture distance super disorder","addresses":["WjHcNKgBNZFjpPYiEzt3NuQu1Gvw8Ha6f1","WY4CC1BSrTsPbqE6gHw4NZyvdGAwm3mcJs","WPfea5UF4uDmK1Jy1fvVwtRB31tseQuGLa","WU2aAimieGMSyN4Q2dp1QijX7RujmkJ2tc","WSCM7JQfRS3mhskhdz1SAsaS6oPsDEpkPZ","WbJLWgJGenczW7zxP9nzHrKK87B3VNvm6K","WkoGL8j51f5RsfTSJZDW6b7E9UengJaycd","WksSzVzBP1ju5ng3nzYFh3zGkdUMcBDyTP","WeudqBphGNnATzAShEUC86jsXgpf3akPwn","WXKqBHNULDCmYdMPdqdcDgbG4EXkBxAq64","WfSeJHMPRVaqbVnJim6JWf3b2yvBZ6mHKx","WYTXCPRzmvXxiAK5rqCm2qnXe5hkDXFFKQ","WaDTaMice6ximiCSjVp6Zde6sJCx2ZqkZY","WeBTiZehgELBureYMVDqvV7TZqtUVNgKkc","WUB6vMSqYXQhw354SCUrAAHR7kJaP5eBnA","WSr3KJTtuJVNwPrnUuDSzgxCAid7gCca2L","WXfnEr5YxLtgV63xc5ouK1nxi1e1nHSs7L","Wa9oy7CnkADySHv5kVZEtEQ8BcnSGECr5M","WiCriWP2CN1aZUmP2r8aNpwHYQYB2gYi58","WfjUCJFpNe3AWPLvU6as3wwhFxSkjbGsPd","Wm5YhYwqhQJF8kMQnTTWqGjbcFADM4zHeA","WPT1WKtNwCru895rgLPbBe55Nn1JLgNLQX"]}, +{"isUsed":false,"words":"inside few recipe hurry normal cool thunder prize can brain step horror tunnel gospel height olympic hazard amused field rocket awake surprise cabbage taxi","addresses":["WbDv6bzUVPwKd14Wcv9xEagavxAMrtfajt","WmevahDfAGPVfb5MxauBmxq6NqdC3WWQLC","WbQD5R3VwRaxLeN7g1fQkczYuCwCumRkcg","WWPL3UQACgwVDEGNvJJqdTQMTrYYsSeviV","WmkWuxkAaTxuCpPvwnHLWaxB493wRdhsDx","Wh8iPsXpRNvdY71eRRjUdRegE634sYNha9","Wcmx1yApedGCja1p6ecgcG1aixWhHuoqFd","WZuWTUfiGRMsWdBBkFaUTZHbke2dp5RTsw","WfaEYNkiioodQVVELjBmSBphXqMTZ3pfmF","Wjc8acYYLvhtk2as2K2sfmGNQ6WpxbmCib","WcdQUYgkJfQH42zszDSCzNLiWji4Juy52M","WRkyrxfMAngVTso3myYeDnjmkdAtmJe39p","Wga8DVR1UuvDNVtgToTBPTX7TdVAHVW57n","WTF7X55UXZvyR6fBbmH38jYbgMZEBrxLbi","WS28pP8CXkgVpDKivXYuPrWz5zQT6xYAiv","WiNNXFWmJzydoNrE9rDAhAMs2iVeSPmDrK","Wfr2qCphkaHrCnZJEuxVXYc75WiTQXBkYo","WjqTHziu8VeVLsTQUiFNCTrJpV9qmJy3Jf","WSwQE3oejyxwehSbXury42NLf9QVPHyJBz","Wjy4gd7hXqrL6EhsG2ddBiag7RpxgoJ8rC","WWJxswFC1asY6trcgjt4rfYa1bDXaYMfot","Wf1avY71Pqp82Z651pWshNrLQgNAU8xLJ5"]}, +{"isUsed":false,"words":"vendor evidence crush powder replace source ignore pear antique topic bronze fat inside square jealous warfare result idea fame guess order link obey evil","addresses":["WjSgzAAtvaPXiSAXAb2aLKA9M1nhF7uRQT","WmMg2GQ1vYahCj7BGsi2X8TYz9KJw8WcyA","WbKKFoz4ZVeWALdyScPbmKrjKL4588JJCw","WPm9MM9b9oQbMJRn4Lpr3KQu4ChbzdDqB2","WTAXk5oX4jUG3VnQ8EFvnBaF4U5m9Hj9du","WZHNFZ6oGHr15XmuswTeeeZzbZbxp3thx5","WRfPvK5cZYjKq7YdctRWenBUBmujDEDoeZ","WkA1uzbrjNN57DDMFj83DDxTf8scPKiqGv","WZrx5fNX892b6gEqho6Qw3daMdUYNBfaSq","WfLjydDzTa5raSSdFEAhjbgQT2LH3pDrFP","WXhvH5nz1LghWNxAf7RxGduimvuWvo7DQG","WR4jNiaLjVYZBqiMnZoWxPYCNU5cNbBEKz","Wjbk4y6DemPirPs3tuxXLu65X4kF7YeSCJ","WfvfsE4tPNSzRD16j57HSdrbUK5stB8MAK","WaX5dVNRfAdH9Kuseg7hH2gMq7c513kRW7","Wa9fGD7rg7PQatkQYQKA6T2t3VKWLu38nq","WhLqaUxpe1TeVTPhByuqdJmL16e2YmyGs4","Wm5ujpGGttym1h3kNuGJkrHaE3VZEctvSh","WerfbxjBbGCqNNmmGrk339QpXnmLzFdeyv","WjNd9ub6F5sUo93LwQ6ZLedp62HNLjySTs","Wb7eBLyVj5gYJ4W2WTMY2NnbJeDV5Y5o2F","WXpuaT2KboSMnBMi8DfTxfnQXT4YDoToB1"]}, +{"isUsed":false,"words":"cream embrace hint direct cancel crash huge athlete whale buyer rose brass marine degree panther board arrest broccoli segment limb nose digital squirrel tower","addresses":["WR2YFuiubcxbuGQUB3zcRFdCYstYtwVfWv","WUYa9gzbfu3Z9Z4bnLrhh61BKEuaykkcsL","WW88cpLwYg6UZPJUkgHHFBzMAcUHvarueA","WXE1eXJL6dRwDyYds8cBavtt4U1hFu1FKA","WZiYpyqXGpwEUcNrD6q9T6vxPKV9aYrGkE","WYzGAFeLBmi4r5NjhMrS2xNG2eGRr8R6cP","WUKkSDrHC1ewfy3wDmEgqWh7fBnuZr4Amc","WUiiSCx38FmeC3wAr9GTSNsV1UEtCcqmXk","WjkNYJXsFGbgjb7qfELn4KhW6pw1qL2bpz","WmWrToV2LdTibJiSotwpjNtubdvRGtxScy","WZqAba9dBbxjN4trCr2g3UW1yLvkoP7xKq","WWk5NxHYfk7giAW1ywc8tiCdwprawnvZ2P","WhCPgi4iJsdD3ihjtBdipHy3vUz55E4N2c","WVhejaJU469RqzmffGmTpAf89NMZzqkszA","WTgxciuPRMBLYaMnAxxMF6AFVvAVnqQH2U","WhqiUuooByEooRpfGg5At84vHSzQqVHSRU","WcHWVYDGmMpc7QmuvSUVxe1Yw4u99wxfHE","WRFFY2CWe86coSBtqyTU627zJBQD7TFut7","WSZJYZJgZ4K5QAxUmmZdcgtK1YZEywhrgP","WPU8bWmKocnYz7tYe2v52J6aqmUxw1ds2x","WhbuAR2eSQLvkkyCYSdbLtYLQobUXRomVW","WZvMMkakVdhKrZKeRYEEyS3fnaeH1yx1Wb"]}, +{"isUsed":false,"words":"ordinary conduct shoulder topic syrup permit planet bonus chat lemon innocent chest shadow around course device neither quit bright prison sure color theme harsh","addresses":["WT7XkJNjXt8JpSAeQb4nXzSRkxoxQQmAWG","WaK4xkwpEfczqNfXNAfMGwMnbLmRs9Zs4U","WiYAJzw6CBoWxdymyg5P9KMXvUta3Ae5bd","WVgon2HwyU7FLwyMwxFHZySXKhfp6xcCFR","WbpUaqRtZtfaATZ8o53w6fwiAJsf3Ta1wj","WZZXG1ENxR5RjGW2w3V9KHwwcRboq6zm8Y","WVecbWgSCXV9SffjDhUkP7WDbTCvWZg3U4","WTW7Duhinw8AJqriX8U78qNygcf1rCsqsn","WagHjS1ZbqfVaaD53T4ptVRh1kX64GoRv7","Wc4KiEWa42AJe6pSudgqXuLWnJBxzSZ38n","WSKPBu9pLAjCapWqTvvPT6B27CLmUoZuMz","WWn6krrCTbLmJq4coHSem6MXKwvCw5Bg1Q","WTT7UqzBGyaLj1JWE5c8wqU9WUsfv94SSa","WdoEqN86TnStaSwPDsaRXoYuZ8bUwjU459","Wdzg5dndrRWZGmEDaJFDbys8GTfkXZSwqb","WZp9rgiGP4gjnbLrYfJomXU4M7nVkUZafb","WPURh5oSLV3s9UfgVzNQnd4HDCP5eDEUKj","WmqXdKc5XXxCgihfz2JrP7aN6WoMcWrbqQ","WgeF8jwBGD7vBeWBg7LAL8Rzb4LrZCffaT","WheEVXYdv4bLUQAXP7ozNGcAQh9bsLYK3u","Wm73SzZeu9SYrFMTNKmqpYnB1FXHJsdBGU","WR5TZ4QR8ojW99AmXJEZtMgsShT41eEQ31"]}, +{"isUsed":false,"words":"install dove believe rely cover unable robust movie either raise noodle word toss laugh relief pottery ivory illegal breeze nominee smoke ripple across remind","addresses":["WbxMCmYaq6wzru2Pb3k1u1fiyP73zA6RaG","WkRpSNiev42ouSQaQF1sGxTfxWNBFgVuum","WWQvTKZmpoen4AXnG3AoNWpC5ddSMiqbZ1","WPfaib1BLuqeDNXBSdfAUTiqtfn7LrNZnu","WXQbM7wBL8RkFsFjG59oAdmFY2R7s9PTwD","WUzxwJx7vr3qgFbNxuGoQqfE8rgUAKzykf","WNniNaK6fvnjXDqHBuFsHU9v55WZJWwbT3","Wke8N3u316Dcp1Hg4ZhGc7y5rN6bbehKWe","WUXHrv5BaTye3iYsytvw1sUdvD5tdWqGMv","WX9B8dSKfatJCLMc4PkeohzZGmBFTT8s1H","WVBm3woK8P3VwTuMJmaXf3bmpiDHs5mXtS","WUHnyQCJCzFumkpvzUQjpNKeiV8kWqVps6","WeMsB68SMsrqiov4dNsNXh117GnLLS1G6c","WQ9k4FtjSKEsF5NuQYFXuahYmF3dKt6NEW","WNh7yDLVxkaAXJQZ6iDjZ5cv9KvhcPArvw","WPKVTC5ypbSs8bdC7TnXdf7Mv6F9k1zUpD","WY1SCNzpxUoF5NSQGTBKfogQFzTHRfq5Kj","Wi8CSYG3BnTD4RoCFeQNeQrkbksvJmY4cJ","WWocVMFaZt4PqE8ck2hBpLz3XsLXJh5jNg","WeWJsgjGqwDAx2NxzzuBpqo7RgEnovq3HX","WZwR6V85FUuMPLVmEUvuszcFfBwWncmPKW","WUUvSc4LWyCjo6eQjKiiVjH4st55Ysc19i"]}, +{"isUsed":false,"words":"mirror blush erase liberty design hybrid other deliver trouble wheat thumb style crawl poem chicken feature congress convince gloom verb young giant science youth","addresses":["WjbN5vxVyKNLevN4pKJ3ZbVez1d7dgZScL","WkAGgrDvrmmq1BYdt2PmmRyVc9ShUripjM","WT2BT72iKAFgs6JEdpjUroMTWUJsn2eifZ","WVtCK1yLpnDnyW4am9Z1StYfsCz1T1DoU7","WeUW5ifqwVSTiYpWRioEsCcVwyRHoyB6Yi","WUhZcXTYuiH783wJkMSbUY4j58U7PDxg4P","WhmgfHHxQMLBxoGxZcUUB6zpbjGQ2zju3z","WSvXvNch9Gg4FXpdYv4wXdv9xEpk9fgLrK","WRJ5CZB74hn8rBNBWHYUXigdzG82F3uGNE","WTTJbkUwjpFUEvcsvvHtdStoY75Sa6Auhu","WcFPGbAmvcxAk3Q4Zadmyho6e3F1FnBukh","WgzwZYC9YeXEnsKUZhmPSXJ6bCA2RvkFW4","Wj7UGz9KwoQbPaWkBzcrH4zQ3RpYTKoJ6g","WU2YMZNxQj2DxiHBQSqKq8ZXPoUVvXvqbB","WVjMwJm1TyEyF1XFbfg9s9s1CAGXAVu1nL","WZTX938KShCGhnMuVco9CVHYfr7xffeYRZ","WTMrQof64928fzZ31RVS27GF2Jj5PXPRZj","WjRX5q2Yq5b9kSDHbcXShnWZMCughh8ThB","WeLwybSMcJsudNzHSCQuh7PLTCFMdhktJ8","WfazwQB96XeR2ayL9h4mTcQccLhicP86hm","WkKjSUHgEiAyqF5SQuvsRiSwrWguc7ySEY","WaG2eCZDkB28XcbsNEyv7i47Yh9MJo1ysX"]}, +{"isUsed":false,"words":"floor wagon index will logic coach hybrid under figure much moral ask what sunny liar marine shoe prison thing exact alley stay unhappy sunny","addresses":["WTPkdUKgqH9P28JS7xZwGSeQ7DpagL4RL2","WmZJWwVFJ7nhLk1SR2nC9CozBxHrLFRpHK","WhzFTo5TBioc8yaxPw3tRVhdL9gFGEdawn","WQAjTitNnwNyPxsPig8j6nfRymHMSsUzyG","WUYsivByJ26irNV1qhWWw1rUbzQo6do4fv","WRDccF61e52acLQu78FXEnJqFDzs2wtfzH","WU8wPH4HNNG8JHqVSLRUaoLAwMRdLb7xF3","WbFFZoM6xpQHLKRQy94J1J2LftrSoMHnuP","WPE5xdGdFZwkENxM6bXC5ffqYmZuEeSsrx","Wjnytgjdp38Ni2PWge2Zq2v6AzW16bMXUq","WRAkEFsmqF7Z6a4nBKjRL9WuuwXP9K5V7N","WUiBf2gyWmo9JyYCUMSSdKajUqgwNFZyi4","WU5GcJGbEoLHCL65JfYUNaFRU54RUHirLQ","WgsbFpjXDVsauRp9B3qixmxNHicag2JUsd","WmfwEX8nqQLcwPQYhHnb4qJtP9n5qe1r8H","WccZLaVhCXdeTzb7qMhp38rW1Ex4sva7Sd","WPmSMwaFTbgUzoArAU7DeVLdE5DQZ5uRki","WXLP3NDMRUmakYyd2Y2zpVTs2YgE5rrm1s","WfYnEHTTiZmDdLUmPP5QnvX4LvEbosMdjQ","WRX6MuWLLc1LtPkPJhbLcnv6tH6vBDohVy","WViveGnQkt7WE8BPgp6sEPzosb5gbKNSdE","WYSmuXfoJe7Lp2FP6WE5UzH6ubQME9uYhV"]}, +{"isUsed":false,"words":"mosquito powder village discover ball tip save lounge hint rich coffee organ cargo laugh fork law verify health evil comfort card dynamic field detect","addresses":["WSHFx1oUdLCviL4zVAXREak5WfTJn1yrbm","WQgbt21JZSvKNtS1yxpheQDfC7ctL7ve9R","WWPC2Kk99RL6RHWVjYv5NXmqjBPZ9eiZCC","WmutqQhdByrz5nUpbwYYEsJzB3Z9n5zqPN","WQzWKC7WMZRQyWLoeAXFnS4qh9Vme1r8mF","WYvUvhia1Lks1saqWSGkWyH6aHgxVFFFTR","WPd68WVWSDxx9x4NrNq9yuxccbDBqGvnVM","WTFQpiMzUTyQ9aQ4hj5vN3QsR2iQkDfVUH","WRVPzrG3Q6x4MePKT5vWLdzD36PyZmbMJH","WZPGmhoV8cUeQeVNKyF9HZmn91xK9zcRJf","WjKujmUYi5snRNbzNxtadbY5BYj25QsYJ6","WTUEsG5cP8FLApxi2KabTttKEbNik1Ehk7","WNnafw9FYcucynQoMigQQ2rmzXAbJon1yx","WQnzsgPh4pVqsVkQDEigUKA3RuLtDjaFZc","WcGsJY2JgCAPyeZnwVBGip9z2AzJdfj3Jm","Wktgj5rQpquv6nPf5YTRF4igPjLriTxWmZ","WSwh5wYVt5482DcaNiaCsddGrXD3rY3qES","WP5z4Y3TVkmwfFbspu5B9JRrCCyWjayom5","WfEWaqU4AM6xwna2BJCnd6ksTE2FibwHBc","Wf2FVz9pS1gpnPmpcgo8co52Ek3FbGGCZx","WTfKkcGSHGeihuYjVbasPYwzqS1n3h53zD","WjPfG8pG85GTAs6a8MtP7fFkeurBrvfF4D"]}, +{"isUsed":false,"words":"suit suspect suit clever tomato filter rug master bleak fabric vital require office volcano tilt police skirt behave ask glad upset clog window toy","addresses":["Wcrr7YrA1KDe9DAFjZFajHpbR7m5U7A2ia","WfFzkoKTuFsN3mcd1B7UA9rNFZRip1tWfN","WXbcGmjx561BYbpz7hfwgi4etDWPkLT7jZ","WdF9sjiRQ2yd1c6FTDN3qbhkWPoiyC769m","WTRZG6yKALTs4YzTXgQx5bhT5qnY484Bcv","WkZqpCkvJggMjfaDmD8VjrXc7EmWAECTQJ","WmySFCVcYoeJBJaUuimhBxhB9jKaRqBDSK","WPoNsHTiD47q8Sh8ubPe19pvBqHgJXRGyn","WRNRq1riMpi6iQrHMj6vn5snNuCvP5qSq4","WbATXDja4SYcviC4ftCNMhMM8JZbcue53S","WTGUvmBK2or93diiUUh4dKF68UKWx3mVgd","WTGVVdpVn6oVHgy4V4p8zt5WJkqqo58g5c","WPo4V6ioKw4X1Nu7onqeyP2ZjwFUK7BzUz","WPkQbMMXLocWwfScvxcKZgr8cwEFWm8e5d","WZ3Tf1YtJSokqVHbGBrHjtdPskkgaD3hr3","Whfi9mCshmdKHKafqu784usRs53AQTLLzT","WTXshWZcDMsbaaNa9E5tnqLLd9SXhTmkkd","WbtMFqorvfb3Ej3gva1CxAFU6krzhgBwXm","WgL5M22RV12PSwct5KrGVEzbxqSRXTAMFm","Whq5MTrkQCGXDef9qUVxarSA6moE9me71o","Wd6ckkwLdPL9SW992duZkh2muUgeHrzv7N","Wc6C7TL8rNoKLoTrRHV3WyATB8wjQ6CwJV"]}, +{"isUsed":false,"words":"witness false decrease fix foil tornado salt desert weird drink galaxy torch add fire crop path clog ridge seed couple humor effort design liberty","addresses":["WR3mv5hkWav54HPknP4fLBUZc9735ufy3o","WS7XjK7BrR4cBoTbTb766etJNixzwYCmHX","WahdJA2VUGHco2MXkRVjLeifxvUTzF794G","WbJCcy15sTP1swNYJH7Sz6GRFN7YbP5sCQ","WbWRVo7cFGKAhed8gXGGDAVgPp8jbPac7f","WRTn8rDZkSiS3hoXD5Xm2cnaCPKSRZDcc1","WZoQ2BphKHpmxfUrGL6DAbPGbDcSHjtuP3","WSQkRmFd4LZ9379f84k2vYa9QDteQLXmLQ","WPudPPDeRHWZqGRLSVmyqfvDCekFdJMXDy","WSuGwbnfEsCH6Gnxq6ySnzzEkT9v53FKUP","WXR5TLnUw3cSRD2tACt2TpgeJ7owU484F3","WSsLAk6UU5WEuNk5DPoH7oQom4btML6223","WbuYtpsffxahJQR9EhLMSnuSgNZGFaPzN4","WUZFiKUR3SKNX4UZ4mgNkyb1pX7YZ4Z7ra","WcycocfWVZqcUy7QyLf6MqkdzVRP3yW4sv","Wg8D5q6EuKNYgBGLDo98LYNc5Ap2D83quc","Wcxy1o8z1TfogPmB9KLpG7EksAKEinkvN5","WQGh47Ei4H1R9bm8LhvEjPwWWpXkixjKZ7","WbW5jNBY5S5PYmFwLzoZniG46UDBLxYQ37","WT4KBZA3h2B35QQj2isSWh74kNWWWbGvjk","WaxAqJQvQf5zjRcbMXNqc4fHJEMDHa1doE","WkDF2zKWRG5conZ7odD8kEzULVjW8Agabz"]}, +{"isUsed":false,"words":"promote nation scrap tomorrow breeze fashion text segment such spoon orient poem file taxi abuse tattoo tortoise source hammer pupil year celery envelope giggle","addresses":["WVcrvYoaPnbqZoghmP3mZaZ1khMw1KU2iC","Wc49xMLDrFfFjvS2srarV5Gwr4kErfV1Kt","WjEfywRUm4H3yhdxA5dP3C7vfwxgm1A41q","WZrpkFGcDnqzM2i4dGMAG9tKCEp1SVUUn3","WPeAwGbribLmmUhiJcVL6KN5EYZWkBCQCp","WRsU78Mrqxecu2qL1fppjbdmvPPVXCRAzc","WfSgpVbe2PJe6hxUuXfB2kPytnU5ssZuzh","WT9dw8BUid2BtLQi2FpWAaTFgbLFy7NbBN","WmaD1gY9CbatWQ91bAiPeobHtReUHA1yrD","WetPpcgEuCJuefiPMd7wrm1UECTPiMaBpg","Wij1WUsjqQNYzwuBPc6V25jbwrjU2NpHYe","WUDbkXQ3FCMtkQPe88r5jLvj6fJRyEQoYr","WZmc7CvUGEfJgvLFTSubEDgXqFwpjc6XLQ","WiSxts7znfsRY9gUTm7tciHbATR1EagGnb","WXPahrqc7MD6thpYg8sfXaA2yU7mh23xoz","WeNoH1SELbbk73DSYHZQeG8ehmguaCzzGW","WQux5vX3DySfmo2zR7rbupJR1zB6Mg1sRv","WhXoCEFLVyrcZcbZYSMhi5vWMcmgohgTqk","WSJQMCPbXtLP87E8bqqfbUohgudUj4vXK7","WPbDGk4cjZckxwL9yKLBmC9rbdx5Y4BQPE","Wck4Ev8UGYTzbGUDiU8to84Bn4tgiuSJ67","WULYCPwSBsG2gdX9VmTGBKWeBU2Pd7g63K"]}, +{"isUsed":false,"words":"gap physical match armor rail neither festival just spread friend motion alpha impact tumble similar vocal angry hover accuse slogan file march sponsor light","addresses":["WZf9AmbSyXTCeffUgoQWeCrBEnVgpVfhnB","WZFuYyF2aP3nYZAqPSfJQ3ucacddgxvczv","WZ3RFd6cw2j9eXzpF1Aw9ZCKYfsrYqizVM","WX5XD9emsmbUeNzhBcLJKsFeH3hPfUwMbk","WYWV2LmFwK5ES3Qje73HLRnHDq5N42Y3tX","WawMVM2BfZwPt9eQD7VLyLf6af6aF6Kdzp","WYqh2LRYBBDtutjvGSF1bZDY3P7N6pteoE","WR1wmTackA4H6ZmJMKgpzWbZxaoXzubsqk","WSRyFPKtUsjEFkT9xgw531Lesn1M2za2jL","WfCVXTq4MXcQdiFJNHksGgndHabTMLUNK8","WYaoq71q1hUJtfdRqXTTVRJ8NoXpDTKLeM","WPncvjBdbuaf9pdgQzZqLtDdKovzHemh8x","WWuFmxoFRGHpAuAnXAzX9Efn1wVWeN36zr","WgWkGNDKqUN9WnMDuq5iPXFUFRMPqTwHj7","WZTPUDkJdQZPMYogEmoHweENpufMvAKjuq","WVUHsAK4ZaciF7JnzqiYJhuhGsiboirtj6","WjSwr98VKfFJKK7hJcCaGNy8xdH8QHEK65","WVAHMUn9qr7X8V3av8fu81ZGVB6xaGsrFM","WdLBqhrJ5eapCSAkEctzfGXSeUtss1hns4","WmED47vQYr3qec1gja9xJBP4JSiQYFcXiy","WWG42u96QSTTdbr2ckkx315b6gZFUBpwiS","WTaoJQzqicbuhzn3C9eBwzVWaBwdcfv2Y8"]}, +{"isUsed":false,"words":"elegant flavor business indoor clinic pear gate dust rescue canyon embody remember unfair accident style illness radar inform fade kingdom jealous again joy color","addresses":["WSut7csCqD6AqJUEHQMUA5RU2x2pTyVEmM","WQG2JwTXtcpzNd1copWH3mL6XCpFKvqM2F","Wf9UbWQcyxX5SrWBXcfevoq8d9o1z76Qcv","WbmFce8qNsQzRbxRqqfS7CY8TkiwsoaHKJ","WjqGA1J3V8xs8u9eo6sq3a5wHBdPDNgqYT","WPDEruJRGiqLtfHGMNwyEtkVWTC6nraYw7","WPFSn1ffvursYFj1HqFQHWCEkQirhxEHVY","WUFgZ5zQX91vbFoLe72U1JVkH6TpaMpxyg","WU4vbFYVTX5FRS2C9AwtX6bUFCwVCRAaNH","WkATZhNefCXEkhrRFjWntc2LA7cXpZ1ieJ","WP1fHa5EAyofkowfSwrdrzPNt2h8ctj2Be","WPhxk28Aq54jJNZxc5KvgqvzgD6jJLVCP5","WfJ4fxF6nc6FkNP9bsomRzz8GcjRVRY76k","Wm9J5acyfLTSETYDC2b7hGuBiz4MVJjaNn","WSpHnxTo8RLP5kgDaHchkocj7HRWFi8mjR","WUb9jc6Gahboujeo3HJ7wpV5Z7y9yeWUbZ","WmV4uthjCirqbzFEcPJJnJy6CCKC4Wk5hj","WjAz3yupsHqUm6jS8NmjL1ZNPX3PbJt755","WUiMQE92NjsZpgLdsUnABspaWQcwwvZPQ2","WdnQGE8fazZFPGEr9KCVtLwYwU7uN2f6sW","WX4itDFZRfvR2e3ydundoTEkujEmgUvXan","WZxcPfxpFgdaAk3xZuP9E7A3HU22t26WWE"]}, +{"isUsed":false,"words":"fog slogan fantasy canal neck amazing slow patrol rival target barrel jewel egg they ripple only shine gloom exotic spare couple bone swim cave","addresses":["WViReKs6htDCt4d98VWDRFfenVk2MVKMHP","WTgUR2nHtG2C2R2Kk3oTtQpNgFxSyi4xpi","WiL3nooVUwZ8t2YDjraJBCiZNKLs2dg1rK","WPEpEdQeMbrik2Lif9xLmzom71E44CxKGz","WboVZHLYDpV77JcjWbKVY93dYiQMzzXUpW","WPmezHzMBqeFJfCk56R7XnvWbXPswHkUzW","WdyJ6jh9fRZSeXdBNYk2qF8LroNYNLtE3u","WU6SMcT8C1C4ATKVmqiwsjNjjQiHNg8gop","WTQYeGuyhgd6QZE6AWfxDXvTQKJz9y2FeD","WQrgGvZM5TvXzMRSTeayr3mCj76o4wmgWi","WiXdZzc1k8M9FLxV8pjhQyVWCt7GppBiN2","WP7MJr8onnq6Bf5h6bUx6UFrBk1TXaZxP3","WioRHTFeNALTdu6LFXC8x4pUUGTQfRdc8N","WfLU3ce7mD8bBZ8LpnqtvLTNQ7kpcFr19A","WZApQUAXjP2Yrdftr9eZiaE4ZVujjiWYDP","WkHUauJbjwhDpkbt8nq3xGZR1ctmNvfyFT","WiWepWrRNAKYX8TQwCEwkpdFN725Hv2UBR","WZTJUBzqu4VXafCSU4Vgx7BsspbzLVHzrw","WR9Vt7aoeJdwFAmtDFxoSRzG7Xheq5xFor","Wita6d33ExBEUAkaYL92gryaqvMfUhcnz6","WYbDM3T19oUyDKrpMRcoMy37tJoKffsQxg","WiLdtZkBRUv2RnvU1YtCV2sU4ocd5NWJN7"]}, +{"isUsed":false,"words":"seek slot rebuild liar ten motion report engage submit public one excite armed subway much loyal acid long federal eyebrow atom economy high meat","addresses":["WkPY7k1wpFb2D8X3qN6uN477W5Xtax4ncC","WigKU26oPi6p35u4XadSwTKEp7VpivLNe6","WiA8w5wf29SJoSxa3E9QV4u1nG5YAvQPPN","WfwHVQYqNndkTB1cfApU6JXkqhNh4pzbx9","WSN2kgXPTf2JCd7DHpywh3KradNsinxdCX","We6QXZomELYZ5fNHr8mNhQJBU4HpXihg85","WRiR4mca2bF2e99VMKuhTg6FSLFCeq8Agq","WZU5rQroCcDAwENqQNHLdWYoruPWTxghc9","WX6fdddVMxCDUfFdvCUZT7Wj8MQ3zr1pfX","WSYLY1L9esu6P5HGfZjNi6gyt3fUHTu6xM","WafTDeVm7nFkfSjVkto5BbfgTt66pWtBrT","WfMbgiSLAgSUEgjdXwnFJ9ixUfzFdz5yH5","WcVsLBaHKi6a8tsAZL3j5vXRvwAUgM4W7c","WiRWgKKch76LCMjinDZwDdmkpo3rUQMGR2","WfTQ6HrAFmPNzLPSyGdPM9n4otFth8XKH2","WQnrXUMXKWMS5hBmTMFGt7H4bB8TBNX8PB","WYhGqMsisGb2MCMcD4LbcU6YV5gd6aFLzj","WTKxZwHvvSfx2HMmUZ1Zoz9AfZmAi1SmBk","WW33nZZAi8kKwsF9Rhogh9mX8th69FxnQY","WRBt8odoomdeU8kpvgvk9pPwAiy645oUmq","Whfq5iWsk8EvD3AhjarcMpMaiXJFXRtU1n","WgoNUQr1dFK36RjyycWdiez3LcjFAWiCh2"]}, +{"isUsed":false,"words":"sphere tape boss there car multiply level relief camp neutral fury fine suspect submit warfare afraid twenty picnic atom message between repair raccoon goose","addresses":["WWdjo7wMTCLUUctGT9k4za74JvwFKFig19","WU4ZxnvafnSJk7r1JvswQCcdNRHsQGXjZs","WSiX1X6q62MtWYdVutMR8nzf2YcKMK9XfT","WVRfpA3u6hmRoKDJeChrfiaQLtkTezP3u7","WPyJzRa6fgQeSxhR4VzZynmaHtQquUCeDN","WTTwDi48uJaNuKg9H4crL6iG7htAQftddY","WXkeMvEfYtwmBE6Un65zmyqZWuWtndjgCD","WipYsRHu5dacJ31zpDbRgbk7AcQ2dSY2dg","WP7dNTJYNPtRTBjVnHHZJmoykLuhTL4jr1","Wi9SYiESpdzsa8C1NMKkmSuYnRHXgi64RR","WfWHb8NwK9uSgBUMBH3gy4FiJrcAzfiDCi","WNqftnp4ET3SqzNM3y6wwNq3iVzER6rYKQ","WfLf3C5JuCR4MsYAkau8GYzSqvY6qxzsSY","WfJYfLEeqn6kf317wzPMLUgUEikRMij92G","WjeHerMdDiEnZhE8LYjP9WbmRo2tQ4MWnd","WYWpQxeK7ppPvVqErYCp8gjPjh9JLjPoaJ","WPp3sPCEpmpsKUeF9WpMLkZg8eSymg8Mtg","Wb4paynTQHfDHaTrMDhyCHM4aUG3gRELMi","WipFXYoGDyRdnFVD7g9R31LmY5KttaTCpN","Wm2DDycvqKqPkTeh2YqHgpNt4d1762S3sH","WZZK1Zg91gQkLAZ4nFKxmF3ubFZgFxNeEW","Wag8G7VUjTeoeuJe1g2rkPvRyhNKF2Z7Hg"]}, +{"isUsed":false,"words":"around panic relief echo shield clown vintage hamster sibling cave ocean blood tail main talent witness situate smoke agree hub mansion double later spell","addresses":["WSgFyGTgEZxH1HD7iJaGy8sSKr77kQZrgF","WeWDdC3h7CkWyrCoR9bzovNqe37EzjBtG5","WVq1wY2NxPmS9mevEpv1DQGsn2765DroGv","WmgPvKTFMVCpQUHSj3M9pQaicW8NE5p8o1","WhgFfwJnnfwE3vEk7yvZW3dRNiVeA4BP1E","WhM73s9TvuXeQKNPxrVUDDyVkwfRr6yeHy","WQJoayJ4fyHsaTn2tMDbwdkfgtfpruhW7X","WNgCpV2H33xft2duJkhQ8Kg8ewQgrPPDBJ","WaQ33zoB31EWANpCyNgtGjrsr4LwDWTMYS","WcvkLoeugHugmCpz9wv7tWtFBZY92MdDrr","Wmj5zfcqfFcTaAWU4ggKbBGHpgjqYsXZq9","WfTK7pV3EkGZZByWqEuvuGKkppLPoqSvzm","WZE2n68RtfZwx72W12QEjQXoLGgY3bYFXg","WRSmqki23vtSBvYKs48LTAvoTqZrVoPHma","WkfAWKJVARwh5c6ksnCM45amvb7t4Hs85C","WkXpf8t6zqSBoZe8NzuZD82kisNeazqqY9","Wkzn7QLeLFkgquebWvwkDRato87WNzHq5d","Wede82x5uCY7GqBN9YdEogGuJPMTcnqWFu","WYyqAbzJDpz1T83rnt4YG4H4pDdpHVRZFY","WXdMJMtwPDiFKmSiqB1Jh3s5QM8V9EGwde","WjJK69z3JskEPMPR1ZgSv2uxjeQPCm3Nez","Wgu1rbWAuYF6QYiyNiq28WrVGstF3cu8dK"]}, +{"isUsed":false,"words":"rose island match hood awkward spice possible waste actress slender tissue diary toast bike inject home canoe shed verify liberty kick prize width forum","addresses":["WgkcF8xx6sBngwKQ18L4scxYDaBf1b5wv7","Wdij5R1JrWqipjVm27dKQvPkSUKNy1v2hK","WbESkqLEzLzfu6LKLrZp9hX9DkfGzTrV7Y","Wd8bjBv8cuPYcCrQRatGY4a4XNBd1VNfCb","Whxb5Nq3DrXLqoHDAwenAbCcZjmXGfYysC","WdTwkwS1NwEoa3o1aw3ou6TTb7rZpi47MG","WaYNx9skA4bvWTAX84J9659CCnU8JsB7wA","WZrdMzQhp26ENeZrHR42EaVhkqF2fdiyFN","Wc27K2XbPRbvVeXZWceXKZX1NzRFdTsnQY","WfDFxERLsa5X6bHub1q2FuYRVEzzoWTozc","WQ3rfDu631yL6R84YQZstRYAKsWnmjUs1P","Wm9drrTSNbEWkKR5R4rPyN7XXKD9Gvr3No","WXNBTXFDGtedAMgDzUsdK1ynZ85P9CKaxt","WUmQLoBN1y17ymZG1bsTZCQ9p1ergxrq6H","Whn9C5VMypkEebT1Ggy2ckL951J9DFZysf","WjX68DA1oQva4YiABQsUDyh9THBtCg657D","WTqUsdeekCEwrAcgSwHZhQL3LdKRpSjg98","WkbBwDY3kRF9SJMRUAPXCHHjtDvHnaxeZ8","Wm726uxqKBfd6gzJv1Ke5UBwqMz3B2nth7","WYh55epEsobnyp5ps8rgv5jBqxDCGeDkMM","WkNUWx34XFzbRF4nAD4cBiLKAGdYXko9m6","WesamaBRNbrn9NUAdjgax74rv7gWKSGj71"]}, +{"isUsed":false,"words":"spirit cover peasant basic embark pigeon grit bundle tissue october craft before dad hero upset party obey similar elegant thrive hip bargain donate suggest","addresses":["WTNmnj4RT1AXdybVeZWSW76A6a7oWuNZiB","WVhKw6nsXAZWwf8zEsrzgFMeyi19eEXqQh","WUqGgEKjmYrCzNxa97fuZqboS9Wu3j5Sey","WU4uNVYJqyafwtJ8KTXkMY1bF1ika6ePgy","WjhBEc2kuEnWaE9ZfQN7wnR77SiVpRPQSG","WRs1Ks5cDH2b92MhD8jcxnEzZwTmmqTFGU","WfzeeW9tLdVhWEXgETkD1TczhnELH3zbzQ","WaVqnuz8jkgH91Fn1FeBE1C8uSJMMTcLwo","WTyqseiRmTYFJRFSKRXV6G1zVYsKiH3t7g","Wc7wXC97qLFj4EoEXMYpF4nA4s4nHtW4G7","WmbP1NtEXtLbCjJVQqGJT8MQaD8eXArzom","WcF4NKGJtN7hWfr3kLsiZhaMkyWpQ4VVFU","WUhJSYq1DhrGEkbJ3433ui5Mkn3yDrKYLi","WfQYkduCQVDz39YNBbKXJbPUw5nBb7xPt9","WYp4p6a8hCc7iLhrBz2w7Amx3pUEMcAXre","WVN6kP1if1zLSMt7M7BJibCXZhBkGtbEuT","Wk2ScUh8c364XR98R2ovzhTxUnqHgYMcMQ","WVMCC41aQrki3ScHtHivWbHrLBv6vWs6og","WRxMEAy9hKd67SRJwfQyX7ep8dJ415Hghj","WeoqRAjJWC9mkpQAXwhLN1MmYeuZJjghhS","Wc4soVhBakggdFrgZmjKiWcDU5wKjqFfcD","Wjjcjte5sT6eBevRk52yTUvWfxuMY5EdBa"]}, +{"isUsed":false,"words":"left pond crucial middle fabric box trophy olive naive gold tape puzzle remove soon ignore chimney find today voyage dove session civil soup brother","addresses":["WNwRZ57mvBcKoAyJEz9QizRAcEs8ZYN4aN","WmxqwCDt4F55QTsyarGLXyosRZz3eh8V2c","WQUCYFT5curiBgJr2MBM3ySC4L2oKVG7RE","WivC2Y6WLM6zB4s9M6VDXqkT9m7CLeNjwu","WgBMLLov7yJFNjMhmL7K3ZPXH21mR6kcUL","WNkLnBhqvAEpuME3HcZc6wmrk5fp4G7wdg","Wf8qGRVQF8SocLJFUToy1Y5kym26U9PzU2","Wf8qsyKAj8Q2TAHxHmP7opnUuh315BV3Vx","WZJR5n2K5WxND5RHvSMaKmAsZu7E5Kvhun","WVL2Zk69Xm6d5Cpe1svMhSB3bq1AsfchrP","WQpBqYRfJ5Yp5L3gMbiWTGDkmZiiCjoGGS","WjDm5ccP2uUQ6Pf84fafymKEB4stpLv122","Wi9Y2msEQDYCuXx9UJLshhcwFSXa7U8Vrm","Wchb4xD3v1iAvzZuF3TT7wrke6ZPxKnLwY","WbPL7ghXzYQrvheqWY4cVo5tSSwRotQFaA","Wac6Cqz68KNm2BbNBhBFzXVVCPenpWR43a","WQv2xxBK1kSuYnELhyMZ4kyP2oz2sbXN9r","WYgSSGMQ8CmhubgtgtoQ9fETXB9Z69mE7E","WR2cLhhTGJ9WREHWRcRec7mg19KkBCLTBb","Wm48yJiqWk5PXpBPxVcDvT7otEo6ht3BzM","WT5GGPW5dxY7g8XdfSPhPerB8QtELTjUYb","WZeVqTQ33NHaUGDnrt6j1wzJVEpo14GMr5"]}, +{"isUsed":false,"words":"mask twin manage finish merry kit seven develop umbrella measure ship squeeze item promote radar punch uncover forest wet birth upgrade flock pole walk","addresses":["WSwwPrwVvpY3kZsvvM97nqcQ8kGHNPBhZa","WTN9AEm79g2K459ANT7CvqS7UXU6nDsJQj","WWrrc9E92sKvJof6Xri3w68Gn6vGtZp51K","WRNxZHCpeKtCzfrPqyfdbxH9sHumAX62dQ","WgGbeXCD7ZzrYVeY4hjgwSgLDs4CrtLnQz","WSvr7QvCExCRhgymMJb9BKxSvVYUt94FA4","WWPhX2LPiqVb5aeaXo2VqmmTBdE9JZbNg7","WVpxoT6VJSjfUoXxQNgskFiYsvTivyx5Zo","Wehg2FJcyoMCGu3zWuUYpqrp4Rh4Pwh9LY","Wb91H4WghNxEuUn6mLv1j3yc2LXRVNNaHE","Wd44hAeKce4r1B4s7dmpNZx7689rt2tPkB","WSPxj9b35tF3mtgEDYEW4JMJk9gFaFL7XA","WmPJ8xLz9aA1NT41bDEGPc61dkuZNcNULB","WaJfeyfG7ptMUZb2MFKf16MZHkVsqCSKug","Wk6y8Y7u9Bv3dTmv2pNEZpc8rtpCEHN2qz","WjpQ2dVyuGUTQou2DdzVodUfchgfeeuxBf","WR5HUcZgyzC31Q3qh6M5xXQiNQwrQfKAeR","WcjetbJu1FpeVVsbaEohiAUKJyrXsHnw8W","WhcTK1krtVVAJpfR29UBjxChZF2qva73ep","WPZvQkjo1wWgBw9WddwwE9eJRS4Q71XruT","WWWW7HgfuNsN7bdgi5dWHh5jgCuxZpJDH1","WcBjx3RdC4KwC6KBRQdZCy1RHXuxCbejW5"]}, +{"isUsed":false,"words":"moon century spray miss key cable noodle behave venue confirm oven alcohol garbage round drip rule dose lawsuit scene arrow enough degree hidden liquid","addresses":["Whg3EGMQHqF1fZ8NXMzeeE6em9JQX5Y3qJ","WjFzXFmJnKcSf731KEv4EUeTCyZaLq45Yp","Wd6BiiEmw6zDodYw1KM91nF1o3x8bC8uFu","WU2uqrKoobse5pHLeztNV6eZfjxfZYq5UR","WgVkCzjd22ukMAFX9Hynq8fNCigczQ4QAX","WfK3bSQYGoTpyTfJmezrvGYVsfFuW8o3tH","WbjVMQwjLHwYZWbasoaBV8gzmG4BY1DKhW","WaEqU9wxm1Lmpw242Z2wRey1X3eWJF96JJ","WUdK1mrw6tyEF3xHkn4sifnwkA3x3TrbR6","WZJCG1cZgQVr8ZDZ6CPyeny2jTn6PfQTBJ","WQWZnG9YrFm87NfAm336vBfa7SrBFTrCEq","Wj4h11uQMnrChdPxm2Zuaebv3FSKzT5urH","WX88WB2aNMP1KGjrCAeKDqL2TMRkLxXcDW","WfJ9L8EyTQUkf4nb9GBJLa5VnPRBW1So5y","WgPNrXC7LWrc9JY9EGkAGzX9EP82gU7ju8","WerBdhNpXoyeK1bqxvsmHAxFGcMPg2zuxQ","Wijz71nTfBoFTo3xs4TyPipYQi5WmHYAdQ","Wa6sijZV28KRScs6h3WiYqAX6EvpMYNKZC","WQfLr4v4cPdnzsh9LMsJtpRWJNusPLjUt4","WfcH38crhqhsqLV8sjEc1Ssdaqnvb9dLUx","WZLiDhjZAgntn9BpmNVeVzRDGkCAPLv78S","WYN2tKcusWELYMiYNEmQPufTu6XvoiUDnk"]}, +{"isUsed":false,"words":"always ask visual credit satoshi decade inherit muffin race steel bamboo tip pretty arrest arch pepper congress only kind extend expand figure accuse wrong","addresses":["WXSUyeDqvy26m1MYC6gcFJDRyXE6TWX7k2","WPmhF1eMkLpkj8dND6NjW8zk5hUi1Au8Lo","WUsS8VgW8taMoThD76xcjtREJeY6QU5mbJ","WbE2QgD421R7tqgRbk3sPKs4MVX1xKSkeo","Wd7x213xY6QKeFKFjMqNq8JQc8QGbseR5W","WXzTBSDNYGKYYme4u7nK7K6JvGB5xinbfC","WTaLxqzddGsMBwyqwpLRx4PE2SjsdSART5","WfnraExh4MJjwttbSz6hnDnC9Voeofhhqt","WiJX3Me3HnaMczdQb7RzxpKhf7q6YJcece","Wa3CamgJwEm4AhgzMmnoCYMMdKTuKQc1Ab","WjjEDbsbp3EnMGd6G7e7gz1CXg6Gzc8EEP","WkT1ov7W55aDG77vGh6Er9zMtYEGTBx8EA","WSNagen5JsVKwkBTQ11gEXvm686DNpH9FT","Whgv7cFTpAe18FmMXUjzmSV9XHiPCFT1v3","WhyAVPrQBdjvhRPHEC61rrjrZc5LmCdqKi","WmcaSdJcNbMYbjzZaN95RRQi1r4BJbB4kR","WfwJmmqzCcPmdVrppthMv3reeqkybqvHQU","WkZBVV3CcNbF3VyFzPdTSFk73qXbLo27bX","WTGUYdEH3EHjVLEoHaUFGDGEyB8DrgCddz","Wgp6QoBoc1WYcuevdUPHe1EGS5GAiiS1Wd","WV3xVqtTR3r6kFScu11nckkDFUEaQJPQ3m","WahjnppAyLGxsUcF2t8DUcuVDPuZWw94xu"]}, +{"isUsed":false,"words":"expire portion divorce very flower talent profit hint volume social elbow glad random grunt collect violin actress ostrich mango evoke rude vital give maple","addresses":["WPhZSLN6zRo4Hq5gwJkDgZbmz5H6kCQ9qS","WdcS97stdt3ibfeEZzv88WgyCkEFgLi3kE","WcgK4SfGBmVpFtdi9Kf4ti8JvNM3oNo8CX","WRoshjVo59dmLLXsMvq8DwJByCrYkRvgd2","Wdk9gcRHE5ghbvv45FS38QzMTJ5jUDz48Y","WRS1ucgoujavbA3mqa6JwtHhYCTNh4s6Lw","WknLGvMrpBPJcyZaqDLvLDfQngk56ddykJ","WjKsZXbhWDVvgzzqXRVPfhCVp9yx8i41o4","WWeaMiWcvTU6112EqeHjSuZENniDasgC7g","WQM7foRhZSTdq5shQ31kByPVKKNV3NdTXK","WdcX3WKpABBiYHr17K5kC3sqC7F8LDPFa6","WfM99U7LqGvXQKEtLy6fyw3iRY2CevcPBq","WZBXFpsifJXzh2yJ4KkFrUu8aebkc3xPTT","WQo4d2HaFjnFHjaXnyj9gWSRxG5iV4MtJX","Wbv1ck73WnLexkJQ7TUFLXRVhuLGaezEzA","WTm3JQ6Tow3nVzJkvY7htbARH9pLsaeJH9","WPeiKYHScLDrA3hak1nKt8i9CzSft2MF5U","WSUMir4baG3PHcUFQRcSGQ23ZWkzbEdz5T","WkLTpb1wSZPei3eU412DikLKPeVEH5y5L7","WYPawirNBGd3vUqZNxFxPomowqAn7yNDmP","WYqJnb4amVzdP5qvYtYxzcHT9W4osxeNhg","Whv8PhdNuPSG57ivMfBNdG3nExzucxAAyQ"]}, +{"isUsed":false,"words":"property bomb dutch search fish gate final rural robust over man embrace annual balance joy wave drive search scout into front travel since subject","addresses":["WgTMHcKk7TGuyN7FTAn7ZfkQ9ncaS76Srn","WTe3eXYbfisiGuym9JxABFb7UpJtto8mf2","WiDd3LWC4EJ2xwGhYV4urSvGkpGQvWsDpF","Wdx9C2ZJ8uN9yWe1ChopvTBjeFSbwg1iYe","WmKf7Ekm5GbdpKJyhKztUqz3DwvYb9MDnQ","WhPUvmAYdqwmmEFVVFczE6KTj257Ty9xW6","WkkiCBhV9F1sa3SHTfsMEmRpdjfPU8NokM","WUS6NDqXq6DAPZpUjrMa49gSGhu6tr46uL","Waf5niqGmnM6LT5VG3xMqr7R2AJELYgRz9","WR2a2fiMT9hSAvoQCQ9WKYCkcwBe5XQ589","WVik645zEaDCqS37NfKxLrTHEUYcpycyhL","WPzq1EhQeWFbjZ4aq2ApyDFFuDZJvfVyJt","WPU3SBmmqebjAs1taXHi82FeVSS7xAxUbY","WXDzQZmWJ8fhr1zsLRP11HfcNGzJWX5Sxj","WbsGjV4DErrRaErP1GzE6u93m4e2FjLKju","WbE9oiaYLcVRNk4vP79rggEeBTAHvsLowB","WbCzyr1s5qyb6zQE29XJKe2ijg8AGZFs77","WSPVZQcBka7J3G4gp5K3FMRDHo2VyBmhDk","WcHNPoK68KBfCjUJgbVk1pz2aVA2fYJ5W8","WQz6CPPZi5mL5wnuytfzQe5WNphuahBtAj","Wi87TUwEMLoJuRynT3L8zRQAtQv2FTS6m3","WQyS4ihpoGCd6W9ajpBpZVrjF9DMHKfmqW"]}, +{"isUsed":false,"words":"betray system correct fancy always seven report detect bullet language about sign screen spoon control night blue property suspect oven tent model catch three","addresses":["WX54HMLar5uLJ3RgRZAyciF2HQhuAPaEVE","WkYJ2ZC1tpyFT9YbF5oGdyKG3crf4aEnRn","WcXYrzNrqxh94ZpxZ8X9eV1fwVUFDNASDS","WZhycMsjFfRT7aHMcw9K4sYE2aJHLw6NZ7","WY9upo3niu4BYCXz3ua7XpqbeRTcko3D5s","Wc9gKMP66ztBmidH4a4uqKF4yqWuj3UpVe","WebGiSKdGrnBb46rjBwu2ScWf8HkrZfUX1","WgeeoW8omKrvyyKUayGqHHyLaDW7ST4ngP","WRMT5fPuwjA8Juj8Ar3VnqgTpA2dB3yZtd","WknReXYk3Bpdw9QwZgvu94TVcJ1UwK398V","Wc9jZpu6JMCM93frW8EgfkH28LZBhKv1rJ","WmgJXVQ2TEeeTMXXqF2mwnVBocVmV2bYB8","Wb911ADMHgThxd5x5AnDfug1vBgAhKmcsZ","WQxCBiXW8fPMK2h245YRiSt6E44J1Qf4JA","WbNrZcZTUNwMSukN24hcTiHoC3qUDU8UNs","WcapGJxixvBGE5oEGLRGMnk3KZHFZ5JwyF","WPDprpgC7LfSgZZR6kDJDWeAwDzEkmQPtG","Wh68wrrj5as4WzJmGckwWNF3SacxkoHzxh","WQH3XBwrTKhWS35NCbdas9sAjt6XwsGjEy","WY9dH2g3og2Krd1r82dheoHQ4RNsxi5HxQ","WZvMmAxoSZt7b1x6FajibSgpUwoDBFyxhs","WbHz3pyADrJLbNkqnX4tMUkpkzjYWdHYJ2"]}, +{"isUsed":false,"words":"able act script stock stool arrest hungry tobacco leisure tooth sauce alpha dumb stage image pudding loyal float apple ancient excuse symptom stem cake","addresses":["WWBNn2QMc8kjzBeAiHxKPsCVkUc3VP6C5P","WZf2ezjmCw3Jq6ya9ghz5baaRjmASSScLi","Wg6d2rhGM5sKWkEHG7mitykvsScEuj1BTu","Wi5B8YmKqcwjTtAN2wPmi8pZd5GJhxBXnd","Wisrp3YzCPnonUpwMn8BjiV2TEsNfzxqit","WQn7AdiNBiLLr99toBjobRP9SeX1WEDgvZ","WkCToYjTBzQCbMQUJ6mMh3z4MqUvoxsdPJ","Wk9VJdwYCy4GujiXcxBF8NPTMo5r3vjdto","WNyvK2RFqipNNPhtBvSYnmVwdSfwV7KDh4","WUmd4ZPBrC1U5xaeuoYcK3VBkcusonqvmH","WbChJq4fYPBd1Lr9stcqbcA95cxE1WGiaz","WXjw8QNAFtJdFJnaAcK8Q23dduaAbtrH1s","Wk8r4U6oQBsLhds1GsiA4TwxD61ZtYYjoj","WZtvU1hREyzy5CzHs9caGNXs3Z4pzN6PEm","WewJ4teu2k1v6mry2zuWD5oruDVX48Gm7j","Wd1ueFqfrX5NX6tT69zZ9y1bZwESjvzmzG","WQrwmETwj5w3EUSdCCHuonzBGuPjxEQrCy","WYVCHWpi3hrCeDVSXwM7ECFMFLiZwEUbPk","Wiu1eJrccbywr1u9uCRanJ97n1ju2K5KZL","WQMaD3MAiFhc24fcV9RrkvmGPtdg7aJQNp","WcX2CEyGHS9EVCnRQ9oRRkwRafab7VZYdG","WUqJDmHom6EcBxd32RKvycXHxz4kZvrAmG"]}, +{"isUsed":false,"words":"play mouse lounge unit mystery wasp morning armor loop arch donkey vibrant meadow quiz mechanic history trumpet peanut tunnel plunge manage jaguar misery join","addresses":["WSiF8tqLmUkXXLh7jcPWTizDEffN9ZdVAp","WVFf7qcCBrEEzSBjcBucFzUjFQQdVLmmAc","WYDbzzirY6xdRPGNwrS2Fvpz8N3Uev4AZu","WVpvcMEdxhtonQUqZyxVCLmNeYBAe3cg5V","WjhabvDG8goRxLuX9A5v5gZLgyam5WsSts","WfY56bmT5rASZBEVPTQGJSVZzvSQ3xdJCz","WZav8TtAUxh25EdNMez1fXUidNCz8JSC8H","Wive7Rz9fzFWnsN8qJbk2QxxgyUbWHjdNf","WPx3AQBQKGFtQiYzzPvQt73B9o6YSyJCAA","WcCc2aZ47wbXLWJVRUKmhBjtdk2yQj1gr1","WXWrgKbSMwqwLLpp36B65FrMwUoVj5y2p3","Wj6jZveFmtKLAUpY6ZUZ66appqcViyEQMt","Wk3SnM4YVLGB6wqsrKxRSuhxs6RjGkhW2u","WdYUUJ5Jiv7prqkyDYDPdE4NbAaSmnkMBA","Wb5kmxmRcpB42RSv7e3ZEnkxkP2duDgfe2","WUdoSJ3EEPeKqsy5am2tR3z6LbhAuySPun","WjRYSe867u1eMH9VvzK1t7Sh9LDze7KNgY","WkoVcpF54rHmW8abu9VaTu9XUgES2LH79m","WjonrZXZwAPsGy3frijwdYoaWefdCDMSuC","WjuYR9jqoHmUciGFeVdrYbPRBSsz2K3per","WSvixQhiMNMrw2GmLvnR87z5zRFJk2AQcQ","WfWCpMyQ3SK8K7pDB1ycybHQ49QXZ1m9o4"]}, +{"isUsed":false,"words":"chase soap then pair method embody exercise point forward egg expect layer infant amount engine result silly used dice similar loop strike scrub fan","addresses":["WZci3oCLX3bT8BmXG8HZzw4fKLcA5kW2jh","WZxS5FPFQhxtMazUCP7ZPT2BuMLcrxHuXu","WXG9diXUMH6Tu2QXZRaLpcBV2TFuc31D3e","WYxAvnXyukejGHFSzn5Ys5GdrKvMvHycAN","WTKfiJDLgek3AcsfAVRyksH7AxixHt85PS","WYrM8dZCBFvQjoYGjygeP4pxy3QisLUFrn","Wjug6HnQB8wMn5YM42gCTcUo1ML1JdFEon","WSZLGKTwyaSCMqYJ6CJNiGmdBDfKs6PMNu","WSX5tRJiTs9sU7G43eA34WhJALwye5K85k","Wb2AUSVr5ivpV8YMHroaUnCMeRA6YvJDjK","WWKEu7LJpAC1e3aGPFSPLsrkQyDNtsbsWL","WPDukzJFaySJ362GVmFUyk2KP7BZ4NmWWb","WgWYU1bwv6bmJByxNDxzZkdtuAQzXPzobj","WPmadg15JuMytS6ptFLx6viGj9Y26oRDmq","WiFauMpcXpRGyUGxxvzKsU5pBusqtR2kTB","WV3dMC7fyXSgRKBWbTZVmASYaMStrWbESS","WWkouUpTKnuq2uNWzEUaMAamJD7pXA9Nu3","WQTApRX7vM8N5sYtr48cd3UdSWDwotZWGJ","Wh56yuqCUqTMxKJJK7H2kJUGuy7W39gWDz","WkeBCRNmU1tok393t5542q6s3s6hAJqyQd","WinXrq4PrfyzA8YUaUuMGw54DDmmz4Z47k","WfZEomdKGiDVVBicw4hsJMUoW9Dv6meoNd"]}, +{"isUsed":false,"words":"fetch fitness anxiety phone curious pulp jazz grunt prepare skill whip arena injury trip brass tiger spell ship lunar stumble ankle habit argue chronic","addresses":["WkJZEnZtQvE7C5LQRnittdtAzsiFDFm5r4","Wf67NAyprhtXn6BsXFd85JK5xpkmbHzLKf","WhsfqG3W33RwMcBFWbAUASTeVLruQyzLD3","WQSC3LYfv17mY3U28mx9N6GSX3DAjbE5kB","WeiY69ipVAb9o11YJBCdenCep4CDfhu6zj","WVT9LBRDKEa4DgFpH7zhWpubDfMYfWFDRB","WTNjohDtqvciV8MCeq9P8pe9zhfjEj9iv1","WfgKczwZ92Yf2P6MSu8qcqPWnqYXfmU67v","WP8w42s4SkdHHqgA2xciyE4ZTL97ZoKX28","WZ8yV51gcuMug84qH6sy4VAxA1VEaaFiZy","WggJvyMbjP1A9JiLVAurBTpyaEEAMwKrVg","WSiTEyYBi2StSnUGzKK9bznsdd5Wc1MwsY","WTWqHipLbaXpkcuEA9btEokznrvXw7Qzwd","Wj34jJWKA6F4dZkkWm6aXWZNjgAW2xwRfi","WaPTZQSxhhq26GcvG8tpY1FiPzQtxSKoMY","WieGYoX1RzJLAeAxRCnA6g2CrPgi69LEWv","WREimgBzSr62NYResS6MfbLuujfVqj2xqe","WQsDWJNMNRvpVRy7sMWEQXATN2Exqh9Nrm","WheSLuhXVtrqh2nDvZX3XdRtjSFWqMJfvR","WkVbQUmmyg2iNaQqL9V51GT1kDm5ftKjAU","WQ6wWtQmd7HibJZnbs4DjTg3TjpTLXA4VV","WaLEVaHSRc3RY2WsH78Ksw2oQyPpLDkVih"]}, +{"isUsed":false,"words":"poverty spike waste unable pipe depth area opera cream item art space update purse lottery antenna orphan cluster what target creek choice corn post","addresses":["WdaFaLRgmEsGgfZ8XF9Sp6Cn1nmEn8sRyL","WR1poMFBnuuWx4Rm2SV3Wiy3N7Ut7CjDp5","WZLzvu5do5a1JH86PskemLkanLFW4L59nL","Waig1WEoiGhL3Tdoms81QiQGRPCc9L715u","Wk3EJBGnxyJKZ3BgXzNtS3t172KGVpJC8W","Wevr4BQAAfstFtaLGJxeD2pSEhzpEppGcH","WgMZk5DPHP4MDmjyexTMNNFUeenoLgUPJD","Wmbrkg6J8NJ7BCbFDxmsaD9k8f6NpQrs9Y","WQM1n1WNAN2x7pLGPnpHmfcFvBLNBL7PHu","WVLhRXgTDcuwtBS4sZHEdWeyBV23925vDQ","WRigefywp7QxXWjn32E4nwXsg4JRSPSvjP","WPS1JJz5hS86eEQKxR7zhL1kjiztqri5x3","Wm2se7ooNWZAQ3j3ztKAhpbGbZjmfEH9wS","Wb2NXdmswZc1iKya3bkrGhUA3vUAPKKWwN","WR1TZMoi88aiFuuHpqjDssjQ39bP3YZU7u","WWMiXJ46cZyswiqzjZ17iBT5n4nurSQr2B","WbFKdpBwr2ZVnH7LYkZBbhz77nvPuBRPdC","WQ2CbwdQJYp7kSttnExBPJnPTZRLp3dXdd","WVsRtVnKfGy1d2ky81dLRddDxdLdaRNnww","WgcMTdY1Uu94WuV8MuCAsCqB8B4YPCyTr9","WZYbeDaq8Saca8qUc9C8CaimDSBWJRTHcM","WZB3DZ27FvuFkqQ7wWAB8mazKSKBa8KtfZ"]}, +{"isUsed":false,"words":"rotate appear deliver cruise manual impact twenty flight indoor better laugh goat ill carpet useful achieve benefit gloom throw north side eight satoshi cry","addresses":["WjUjEUzHWNwgx51BecPLM89hwbVX18bFP2","WdC2E6AVmFLQmC7VUrkKmN1JBCLLggCqDb","WVstWSdp84fN31FQmU9TgLiQsNLaTndEjn","WmxnmZwpT73uwFwMdvbrwoqbyfD79VMFTD","WQVDWU8LUGLLkvy9GowkFQ85JaescjtKWr","WiMQqnrzNCqEYE3LGwiVwZ1AdkXgJx9He2","WSpvTLGsYhh6tvXxcKNeihztvXnyv84iMd","Wg8KrWoyg2nXMcuCv1C71jouCbgKQV247W","WfUjEEfBG2VVdEXHFQotNP7BActQwDfSQB","WYJhZhtvVF5VgueeKWGzfyeAMzdvc54Sdu","WZhfJA81qMWSgdauTrcUA6qeJKi4QRh9iB","WRVCErvaaGUccmnq3YbVLQDQtQ61BN3ubE","WgyBKMYZNshNJsWhyWFobUBtHJ6RWe97XN","WXQnaYbNkK3UiETpvALKf85q8t4tBZCC2V","WgKqWbW1CrbMMEcAHD3csPkxa2jXxBDrDz","WdRewincYR5QvnZmd4oGmSTGHFjJ8gkdf2","Wde9PkzthjfQKJ41N14cnuAEigwvDvCSwt","WiuUoT8i48ovzJRkGPzDE62sY57syr9nX5","WV6t6W7V9UxayUyoo2tEvxAZce4Sjskmmd","WaNNcAJhjd9ggsKL2p1Q95Qyao4FvsjQYt","WgVYmokm8x2aUv5o4VM31BuzC8rauWquLt","WQW5r1ifybWy7BstoANhY6eGuQgFkWgTG5"]}, +{"isUsed":false,"words":"rifle unknown find lunar giraffe aim actress turtle olive hire beef napkin food enforce roast foster husband bean gravity buffalo tell foil clock peasant","addresses":["WdFJYMRB6Ys2WWXekz6PGMrtYqtkJVFM6p","WWomoWvs87T7VudV6NmViCt7Hng4268QPK","WR2xuUyJwnYmaw7AbuZPvenCuzWW2LJiav","WSx68Wn9P3ZEEsaYMtxneNKK35UsG9N8wX","Wc4edVhN1SaF62UzFLgB8AZ9KE6AHdM75N","WSL8unGezdzGwHpjd8Gv2UrfgES9gakThb","WhPANi8PdMxanCy3ejEvbLr1SanCBKRm3W","WiCdaJTe9UMMwRLHBuCUXTACWtsywN1mSt","WghMtLbwoNLeNGSKxMo1Ty23RbMwKBbzKs","WSEiSrGDnjN2bGnfPZxBhsBHy4X44ju7xz","WT7mfpWD1yJ3EQBiPriMf6aTnY68ULLRTb","WVU4zXifnpQsTMpvLaRbB3oAenTLJgeUwy","WkNMqhgXdExupJLz3DuWeiANWWMBMNrj8c","WV5FR8fBTQ3bYMQyWcxSGt6uwrAHPHfdEL","WZA2nXC9prduc9cZAakDwJxDkyKbo7oMgD","WcSzt4HKfwYVqPzNfu6gF7z9LEQUepJMCP","Wd3UER5t9JqsgCZ91atvGMDfCc2cGg5gQm","WYnWFr99NGUUWM3fAm4qN54hL71C5UTqFb","WbgV6i5TUa6bgYcvhHyoSzk7HoeGg8hgT7","WUPp3rvAuXz7hHzjnfTUtEzWKC8PHEwNUd","Wj69KBTHkSFYpYvtjAtgjTUpdZ8dGafUzE","WbaspqjRinmnQXdTHMuy8GfNHm6Df3NBEW"]}, +{"isUsed":false,"words":"merry jewel draw ice carpet chicken second tourist decorate lock inquiry shadow street slab glad rude cloth vacuum gesture post search talk sweet dolphin","addresses":["Wbg9Ziif6t4YRE4gDFoEg84TTKuLjupPQM","WfUfFz26u1hJNKohzC9tkHssPFK8cntbr4","Wch3VhHyKzd3WzURDWmyQBAm82fMeoCGgW","WU3wcjfs7FAv91ZiWfGtynigMk7wGJ3x52","WZP82Td9FFb1Qo9LJsT8HesDNvp5bjyunE","WeTwz3KrzQWPhnaANjQPgY4VET8jmMud6Z","WVLDDYRhREYG8vDmawADYUNkFjngBzHduW","Wd9CDGLMEK5j5sBbnKFHHkP2DLm7Y6oLkY","WSiEKB2dqyQ52fG5FSSSCbnjCYyV9nyyk5","WbLMXptiUwvZEpteyNQC1MgVRZouftsyvZ","WkPb6NZWugqupmQPZaiesoq4ULxdEf3WQN","WY1xjc6v3H8Pr2dgVYdL1aYtQcoAF6c4Ho","WV55Pe5MeFJoLQToaDQRxNSvckcpt9dQXP","WZifvxqCHJxtiXnoEgqddGCRfMVs3rm9jp","WQpWtTazzdrfmvGXuRnUv27HK6rW3v22AD","WYEFWY5zCorQNW4d1H1QtyukCmF2iQdhoS","Wf6BCYhjwgy3JzP4Aw9fhTZoFgMeMb3fJA","WWJ1Aeqi47inooUoVKEiQhDNnhez9FvkmS","WRDpuYdsQyiVFM8zueKDkYNa1WqcPHdDN7","WZUpNzFwB9w4sJW9rmY1FAALzh38tqYy73","WkdDdfqghVD74YGiWZGgTbN746bmGxu9fx","WbUmqdHYKMaywYHrBs51qoj4czrvUsjW84"]}, +{"isUsed":false,"words":"blush intact adjust turn woman wife soup keep industry benefit athlete boss math kingdom quit zebra excuse modify open giant lift story into diesel","addresses":["WiovZLVVU9uHMAhW29VVX1UNwJKLE1MnPE","WUxsgXJ3UCwtufRQcensZYVTaf6WeWzemY","WbZvUg5U2sonLyrdseyifJfBTv5YMAGFxB","WXBZCPDJhkw9ovd3JN1rJkNN3Q1Z4FsUhs","WQETxEBZZdHhCphyrSTKSYfUV63ZXgZVxG","WZFwd6cPz4FH92Q8dXvVGyDV3uqPp6NxaG","WPT2ttX8sZ62PnMKRXfbaWNHz84KyabD4C","WUvtmiFwAMW1hZdv9P6PSfvn33UboXDR7U","WgkGj5GmnzrowCQc3fMwUfTpX6jueuJXmd","WPicX7TD44FHmBtKwix4jkia7Cf3kpEqGb","Wkd1g8wZDA5aYi8j4CdGhHKadE2Wn7eXZF","WT6pBoFznjnDwMWeMgHrCf12WtoVjjCGZu","WXmq32dkDvpEM9mpHo6MmEAcZyXPPBsVwV","WPkVtwsukPyiWRsoyThVjQngpbrJCpMZ4W","Wd3gCQTEfKU9M6QwPGVCrYgS6H7scniEjN","WgPacSQdkxrbEhQJ5MgKubvgd1oJ77xia5","WmwCturRzrfp1Z5d7jGbLHrpHVH7dQQV7W","Wh5CvTLZQanjWBsrHKPbxYgGggXDWZ9WeX","WgxJuoHs5xggqdyZfGxPzURzPxhnyZF6wY","WYt9YoRC8EvQofjWAVS5oYgEW3fHH7Et5B","WTmZg14i7ZqrugjnhdfHXC1Sq1f6JZpkoi","WZztmfrLPR9r8sLGjmUuwfrE3kEtm4NV5R"]}, +{"isUsed":false,"words":"dog like sock twin february member sting endorse quote pet evil survey rotate soon electric tissue puzzle where seek uphold gain bicycle crisp group","addresses":["WRZyLSz22ma6MzncQKtAjsvVMj8utiFwV4","WWzjUZ1nW4xXN3CNVK6M5c8oH2qrAd5a5g","WcBh1XBJEydaJpvpnE7KuBkykeBdcedpzw","WTSRUE7JjhaYctpiUpyjajdyjxQkdR799K","WfuFWKe5ERELxGJM1pZYhrENvwJ1bnCib7","WQbfCWsPK4ABdwfCCQNaSy6H9YgQofv6u1","WSFwvzCYdAjuHYyXh14Az8QUEQ4wawawLe","Wj4CVRgv71wqCNfArPCcri6w4TiCUrvovy","WaLoCwxZzPW4WSqLEDugPMcqZ7i8vGgTmU","WYaZEET39QhNfaUVQ1XHwWyHG5xvfDd8fM","WiCgPkCm71ePCA3GW6Zij8p7bE37vrmhXL","Wg6VmgM9FkSikDcHTpsmUfnB8AE2EjKV4x","WT5JJwonRs2x92btjfS5Ldqdg1seNgrw2K","WdBxMAT1uda2wsR7geePTracQavWyQdkCt","WeQ15ncPzJiLiised4yagRbpmbqPScgUob","WYXUKPM97nWTJNHv5i2FbFGHLRig5pKYZn","WZLn5BUGzymnuRaniyhTB6RQb2gyNb3he6","WPwk8HaTkxMbZ4qUA3pkceL1Z2E4UXS3b7","Wkzo5hAT7yRM3d6uWyfj8iFZYmZJemHR9E","Wc7vhXxj5o4k68QuSjiazRyyWQyUFW6Z4x","WWVV6cRZRumYm5ffzDhWapQoWAfvxCPMR2","Wk55GyJ14cMYN7auU3tJQH81YKn2je6WiX"]}, +{"isUsed":false,"words":"column put poet wheel amount garbage orange fold only dinosaur match way fresh flavor moment type zebra extend trick road uncle secret sponsor venue","addresses":["Wh2PgDr7EMMZVAqxJZRaczERER9X7AJt7t","Wekzz9gmpgY9Sq7ZPopZLen8QvNXqs7etv","WRShkgC6HdQBieGsDmvNBNWifyn46vBVjR","WTFULHpRzLZTyurk6Ce1b4x7wTgFA9TMbt","WVfuR87t4znuF6uu1EuzoWynSm11VR8AKb","WTekpRLeKBeNW4HzY6b6nPw3nAaFTh6q6X","WkimZcXWXdkv9vyjuVdL4GBdZ9dbgJqY23","WdxJCqJRwm4D58TB11aYNnu7vQzcdHgCKv","WQGTnYg6XKf5vNyRkhKeoqr7cgwb1svyGL","WchaGjccadFVdebdQSeZznFSeuidizVKTa","WmrLLUmFb5r92TM4VDgNmtZf6gwZfPmJJr","WgZKTDrCYRYiADqEjZ7z2o8R1kcKUxmbC5","WXvzD4ZejvvFMAgXRsCAWv3sEtkMSFvEzu","WhHL8rkpQ4qGF3TzhXNPHRxrTuMHZ9ZyGq","WVfqhVDFSHZLmjRCskNMcSo8nk3axLK3gi","WWizHVKqSWM79vaDegucginPQjXGKiD9hf","Wd7hXt7xsfiSsYGNDzkjZABQYwjSbvDXE5","WVSNEP9AkvQ2m65rmJtJBo9X7TQhBXak8e","WZtLqLa4rTuskXsY8HGLyCBq34sCeN2f6q","WiSUNvZMM5fqnCaBazWXAtshmC59G7vfCk","WTv9rhy2nmpBfVg9FTrUgj4NrhNqt3sNaz","WXbx3hN1DUKX6tTp6i8aryrDPAWyVS7f4q"]}, +{"isUsed":false,"words":"twist flash dress nice nothing solution tribe move churn moral illness solid column sample august silk involve visit forget inch narrow jump pig ghost","addresses":["WhfgR6vhstWBQBd2CNkVMqjkovBq9EQT4T","WVuygVJbfepHGg6PmNddeZAGn9ruzrQdLz","WXfqj4kfU9KrYxZsZVyUJd5Q84Thsak5No","WXM7PJdfJDJSGtTuhRmH4URdZUmDXahy3E","WYg863rhxiLDbVYxrnShuo8WaLryyn9oiZ","WcpAJKoEinmLFGYitgXC1eepoZD8B9TXHq","WbgjNruxMnSEA2LcBvk9X3Wa71DGDxsobA","WUV9p2HL3mGNxhaAdRbNtNZ3tfzaSH1DG1","WZAEHNNMF1tq5LP6ZmwdmCqdWfeqRkjVbV","WfLgbpDTvMyCPE7YkY7Y6okTZ9Dqa1szwM","WUu6SEvUviWNKV8pDbVsrsjhpQN5kzcpau","WUmXLg8ERukVWw2R3aCDSejv3kSfDsYHNB","WTw967Xi5e7gt6Sosruwf1jSgFeAsbdSuQ","WaQuDG1CRR2D2kbN5q1CRDwN87GXS6YMfD","Wkmja7WzdUnSDu7A1FJkuTo4mQ4JdAqSDD","WP9x77dn67RhuWHBFfM4aQqLETHLysnDsp","WQLwSunrgT2zbWRLLbKz3WexKkibQvVXg3","WhwKNo5t5YgwpTJBozAXQc2KmDAP6NxypA","WdSCJCtsVxa8xQZbT2DNGWfu5WYGZ5N1QR","WYvRoCU3WPdhF8tkQA4Xi5Wb1eGipm3ahc","WPRZeKX15nuvkYpQBZ6kgoS56Ue5ZnoSDe","WZ7UMqPZ4tngkknw13fwGdn1ctLBiaakiY"]}, +{"isUsed":false,"words":"airport curious source lunch sister spread cliff federal resist achieve frown tired topic debris deny age dust carbon enforce filter weasel crucial fox hard","addresses":["Wmw9YKHCZ3DLkoYaHNHJU1p1ZZGSCc16oJ","WgJGaWrpWEsKyH2r6PYQoe4fYECJJz97N2","WjUQEw1AyL6yaCAgSUWp282WxrfnCEiBi2","Wcqy1683P3dja2NLckT4tCFtEW4Lpi6oqa","WdLY9hynUM82QmqnjWgJGvzgvrEjbeYWPu","WVdAefSzqqrcMJQnetjcB12remb1FNeAMm","WmZJq3qZNF5tmyVw3DDYHw3RfEn3PEz8fW","Wf8NEA3JAHHZsNwM6GUSJSQPirv6pAjGxS","WfCj8WcsAwCUhcVej2ohJdNjoK1uVSeKVG","WT7ohgWMfmYjWJF7jusYJqvdp2yxhc5dcm","WccD1tZdnBQg9E4CwRiMFbuYPvjoUKunUo","WmftvBifSLcyLm41ciDeTGqUoqQXE4nQXi","WSAE9zWKtx1WAz8SjqK94yfhS8LokHP65S","WVmbY1mwe4uEg3ny1MnyAyWPjaCcK558YL","WYa9hL5psYfuoHwSejWokqgrei5qp9eLZw","WdPppZFZM439Z3jiS7JbG83zU7bfsGnSxQ","WQUeABUbgHwH3RDJC61SQD7Vu97Q1RhRo7","WfUfpsT7ARnLGpB73RqvxcteC4hCS7d6SH","Wg6GTKuaTDc1yn4XKHXgy67iY61hYjAeVf","WaGQsgsQKVYbGAcCynPEZDUtVw9cxQ3DVu","WbtBhjGnjMchEiBhYkMFGiqhfZzSVSV2Ab","WktzNKzoz3G3vEHBhH5rVUhu226MEUbdLv"]}, +{"isUsed":false,"words":"book ensure twist cup damp whale laptop tiger below eight rely dwarf lens update october lake defy lamp human hockey argue unlock marble cup","addresses":["WViBuvXm3doUFPpdvr4vB3rFtTR2kHVvDp","WhtQMCfPq8WUoHXTmDZEyaNq3rJV2gcze7","WNsbw6LC66T9HVZURzXT5kykZisWy3W939","WaRpczmnfSqPPt7jVnVJQ68mWF7WCqDsm8","WYWdecpJ2YRpVp5fiij8KjgKgBYM14GHQx","WPH6VeStRiBTvmrAWa2BaMH89UnRNtCepm","WfAivKCrVhqJduifWR51SkvuNmbK3qfEms","WTmxKBKWpPXPTDm7s9Jnu3p2f4Cnz6s4Gf","WSfk4PLJmxXuDVWnRughP4m6BimeHcckGL","WRsmsdAE4RbdAWiPpSx324hyv8iZsQ7hzo","WWbm8s4qt8KHWfk3265isPJVABXpTxEKRR","WcPRLfcJDBNc6tVUXewokm2DZFPzFf7Lqa","Wk2GsZL8r8FwnsPWXnw25W8GhuP37Y97fD","WWmPAafUVq96rPLskDqRdpY3UAbvRsLhnj","WTZzGKVSoSoGLANwBtbSjGrV6JJCgtHpTB","Wjp8bmJGtfggP82SH3iKtbfTTABWm1QC58","WhgPnKA2GTtERPTZDTVDcKF1S9RwbqL6hC","Wi28Zx3HMGiyZGybD5btyPSXjrXaJMBN5M","WeN3S2XEUk9EZZDFcGP6JXqCC1Kye9VLYC","WiJxu9hvDp19vbiWVmsDFeu21BH2xjchdG","WYZjAvmuWVR31Ji6LaK4ju2rAp3BEkc8wQ","WXSQ7dhS43o5nE3DhBRkTMHtkSHqtqArwa"]}, +{"isUsed":false,"words":"tilt better regular share loyal false sell knee seven hurt century young speak barrel frozen avocado discover spare lake history husband peanut end cradle","addresses":["WQfYkmySVKGP15wK18G1eQ258QsyC1uzR5","Wi7HfVo4zuuHxsX4xwu1ur1r7aWiBfYABD","WTErHSVeRixPswRbpno5CqyrzcHnqs4HHc","WjiYMquZBf51NeDvHBNxzCTLXBXryvBTtZ","WXEE2cedoLxTGM4b4CoWTNdrXaW8Y6uAaG","WfJKwNSFzimPgdHxrCABBGyGkwUzUVNkXh","WXfEZ5vbqngbQioWQ77vm6oF6a1mLashDt","WgP1BaFhw7Fz8VXb1YHEYFGc6kxjJ1MUFy","Wdj8LoVrbiw4i6FFD2Cxe1GxKd4xXZKBM2","WStBmmiFry8F66urXJQFW5Xo48oj1WfQTZ","WZH2uGt41YDbvLMhcMJRH9hC9P5xwM2nsc","WQGtYfRCy6NmsKuvtfMTHbtvUh9oL8nsMn","WTQWhFAD36vaeVemnbKAnB9fKBaYYxXnHk","WSPZrhzR2c9eXFbNZQznNy3C7dW9GmoPjc","Wh5V66ZpZyYALKmS2ua3LDDC5A6DBUpiow","Wb57YFVcSqZtgCsGqWFBYuZr53SDX22X1C","WisR2cZke36NtfLjYqUMNYgNyT6tDYKeKu","WWP6dMD7xwtuN3AtUeZGaBPxxcAuUF2bVL","WmZu2x8KHMaLLRZd6pjsJn1sZzuNEYs79E","WhDm2hSBF1in1PifrDSeTdmnmL4ejNE4T7","WTXc1uvdPwttqjCRMCBHMm4dT2vdswQ4Xc","WRSTzovqhAD3eUEL4KJPU14UKRQR3pN9Xf"]}, +{"isUsed":false,"words":"begin quarter mammal patch pluck husband frog unique twice salon industry exotic mesh gather possible student frozen someone focus like guitar melt verify actor","addresses":["WbSfd7RfAwPn9W9L85pQ3vCbDeiipAer8a","WmgSaG8w6y9ZjZUkLZc8o2UH57Q983Trpm","WbePAwB6ots2tSZBaEvLFzJcGFV7CueVxC","Wa46qLmhPqk4mJ8CKLHXPcAhgmyiQGuFPk","Wis3pjmVxoh3YeuL1qyooqoxy14KjosGVW","WiQyGZtskspYupBiYAEUwnYBYiBVtr7do7","WRmpAj8vdMVvMjT1gbnc1pQfYHwRc5zoou","WgAsyW7P5wCx3QBu6Qcg7uW83RxXM2bbRa","Wip8Kty6vRddD8yvyE6YTr2FNrM9bukCRq","WQqqF1vogK9Sb4udevYoJy8h7i4r2Fw7QF","WhWuwTtBAiwistCeu9Fi2n7TRXntUbaxBw","Wckna7x8kGfQCf8TpHej3W45biwobiXUGf","WfZxrkkeLEPPdc3u5LsSSvvRQbMxKSUqP1","WXX3SW67yAKs8tqDtE4ZWm1xXUd2adBJ8M","WeNSHTgNsn7dXKT3vHoV2tZxxzn6nXDeDS","WbN3yRZ1cvtvwQdCzo6mqTyzkp1G9AHccR","WSGcEB8vMsWWdkagZxxSN9XEjwiCWLXVCx","WZ82B4WxJcysDN4zovJMdXDVDL3LwE77xS","WcTJYt7XDrhJmLDvvDnBuHFzHf4wotF6Np","WT5hVtwCu4nVfuSgfxQPGsr8g3UEznaHvE","WbQxmjbpfqymN9SRL3528CTL37UXiCy8ej","WbqzHVqukEfqsL41JRsxtseZkP6HwA6UZs"]}, +{"isUsed":false,"words":"enough toe zebra vivid wise knock quantum mixture hammer topple acoustic meadow gather pluck people senior nice relief life puzzle amount message fringe fog","addresses":["WUVEYE2jwY2J6XPKU1TYVmMGSuhBRXdfeg","WZ8ZxytZGVrQBoByLf3QZV4LB3C8N49VsM","WXh3XGsARCJpTorcswcDZya5jFAQ2bmHQ6","WTD6CwRVuyUEZFKchYmQqNSR9BZPKdHpyH","WTMjCtT8Mqr4yEQFAYoggEmWYfTsyFoqVy","WSVkt2hZKgEnNiboL5TreJqSUaDNiqngJu","WfC4mprbGfbF48fhPzsnXEHDUDxDrUsG8S","WSczQ8oTEqdp8pQPL6b7aVmAnSz49DLjZw","Wk8YTh2xZBhjfvkSeADp81zmiiMyyeww8N","WawW377bkB79XRYU13VCDxCVuovp5ExMxh","WXfTRa15u2q2ETRoDiPscZvtqHaGrqaaRJ","WSCco5ZvbCf6SypqyyQQaxwE4SgQqHFx2d","WTYn9vggh9bHQXbe49AyMSv9X5pi17ooJh","WSKY1FEWNvK5ZEEWqKKwJSdVXNra4pL95X","We2rQcWDk8BZVEZM3pa5vkt7b98wLhxfhu","WZzPeQSspLZXirtWj2uEgWYKX5XZFKyEeh","WmX9e3GnnEz855BbfFzY2CRhbfp3zkyiVY","Weiw5v6bqQkzkwWt5AsL5EbBu5bx5oXgRg","WdzWcnEP4pp2V6bNGqmebzThDsmJFJjZ1p","WgpoHnmM7F4CQCuX5bQdB6fW3qD7KD11dQ","WRnaB2DadweJq8AXxwgeVMHX8eLyx1U39L","WexFLy5hcisrkKMyD3eYvSH7s5jZftyViw"]}, +{"isUsed":false,"words":"resemble weapon future track pink volume below season usual coast list congress impose alien stove beef virus wisdom panda trap drop busy imitate rent","addresses":["WWWAuT69bNDdoxR2VtUmzTKHaMfbunwP3f","WfX7RE1sitwyXUrGbXNBfDVpJo5QXaxH39","WkdreyMSWDQFfdNU6o5Vr3NP9pfSXQLn5C","WdnZsDRBt4H8NCKC6vJBJ6SyjWt6LxJF9G","WSjZKwVus1cuphsziA5veV1JQuRwQPd1aJ","WVBiUvWNJEs7qjoj41QcMXKYKKksCrRJ1v","Wgned7DK4TFqJMuT4p2BaxwfmaQx4auNWk","WSv4UXtqZYLuQibn6fALVD918qkSd2pUce","Wh3xaaycofYcJfXsZeApMsbJRrpypckGzs","WhQ3TDJn6FLFMkzJR5fbE4bhUgD7M4VqWJ","WaQSSLu15NLX3QkFkJJd7p1TWrDQXZVQVz","WUwS9yQrBHsJjRMzDsUyRbEBui6N6G3z5v","WYSXLJ8iA6pRXWHP62sCghbDz73ZkEZjJJ","WVdH1zj6P8AbdL5i2yvy9CzEMGPzmWkZ18","WexXqMJhTkyThQY2bcKVq8hrChP9tUdkCR","Wf1T8y6qN84ybXPteBkNXY2S3dAmQLtqPR","WUHJym22mwdnMsTM3MysN3uF9piXemK3Dj","WWAstQi1As2WEqn8FXNMvAEKFErHasH3zs","WYAbuvcobemKuUq76Ga7WHGX1KkWjMzSZD","WVxwZkLPje6nwNUYbdoiLBEjwVvCVp5PJX","WaC8fSJbjnkKg7ZuRExaWMaBMVGNnJCd9y","WiXrjrHke1HG1AaihM2XUaACPGVkvX8kVg"]}, +{"isUsed":false,"words":"number skirt explain cushion suggest loop river exit tumble lobster pride funny educate return remove enroll into intact avoid coin try nominee era shop","addresses":["WU5NLzNLZSwsGG6fnZyWLD7cztXLUuAHmk","WQXoAE4y9obLXXjqnKgw8v7pnakj6djyTm","WRsK8Gagb5BomWXkY2dXwebxGudTvNqubu","WQLTXFGVSXt8bznqnXULU914mWEt67xFBU","WRunrhrpcB7WDbtZjpus2wjdx931UJPnuP","WSC3CE9mWHXDyA22XXQ2u3nT1krYxbuuQb","Wdx7ZC8Jdus7Jy7h2bBNXB7146zQzjpeJC","WZ8Uzza5FrUTwSPrFTwim1sAdLoN1Tok8K","WR8GkjP9KymH6y2g38Jw8ijXvoqZJPz1sW","WQqHZmGqnw1wwxfXq8d5NYPT94EdHZwqrQ","WZ1YNbCM9jSUt67feNsp2D37nGbS9kmJno","Whva6pHdvYPHoThUy3AyJ4GwLUj9Fy4rDJ","WhpReeEh3vfo9pXq2SA9FRTcPXs91zAgcY","WkYo4bz8ibkNwC45TyGHQQ8RBAhQ1733N3","WjbwV3gbaKcTs9GrVVNY2B4pa4w4ojs8Wm","WUThqk7BjSmzHZjRY4Jb78JVX12Bj7WrmX","WR5fXFQYLJhyYo4c8kfUEAf95wwCamk63P","WUqpBumYnT9mjv76c9QcPwyUPY1duR5dsQ","WQVaYL41eFMj3APUzrw1WzwuVnDimBGrVr","WQ6exWqwrHsbTwYgWmzifsA5esqHWk6pSx","WmpztFi6s4yqRLT3361qrG7WHgVf2gaUmz","WV5WSa79Zzi6LrBkggK37twDinS7vjGpjH"]}, +{"isUsed":false,"words":"spread saddle aspect planet share oak major access mom arm such rib forward enter crater elevator chalk shrug dash inform life install type fog","addresses":["WaxB8SL17T5Rb2JvwKdvfEptZzQVjVVWkc","Wc7U9eufHnWxZVY1KYv33eEsQ3sk5qaBr7","WT6o6pq2hzPF12aQ3USXvYtfR2gxdnEMoV","WaAGjc27j7ziMevLdehnq1EwzvP6iKy2QT","WWUFB756xk3qhRL1W1tAcaKenwDfJYtE9E","WdRhBHHPMuVr5DCdWsRmkMWZ1kZL4JBfMJ","Wi9PJYzM4adj6e6DCitiojQdD1C9Q7fia3","WdJwaZoWff2bkTcBZ5TjBPB21BuKQNDtS6","WSbmH5e3EYG5xCTmctXLg5jxNtHgi3tWNo","WgG9tAzSNSgjxmQW3aymHhPQCwMW5Mqe7b","WjHsZiGqpYmrFbeeMdRChJabjMCDKReKxh","WbU2VAuAS6owVYdrirWsqQGkqLmTe7LZUJ","WattJsvK9kUjAgK547i5FekGPHv3s1g7Xh","WfTkVEGaEQYVGEXdsbamiNjkb2fRnAfbp2","WcgfzvKcEcANDCrwG2TC7G9dZb8shcXqe3","WhmrrJ6RY2ye4JqasNbSWouWYPxm6c75fd","WW8QGtJmHHkmcbkor46xfNun8oZde8vzcE","WW3Mf98inzUxzb7oAQfDUu269LdAAki8RE","WR73xxmUcERnVt82PTpt3f9Yq2aP83WXuq","WeT7d9FeFdMGJ3BhmV6S4thTBru6uBmqUp","Wf3CLQnos9GkBB7MhvrtWgNwNFHqKGzwHH","WYB7WsR9R9J6PtuUMZJzShMS5BtpkEjuFT"]}, +{"isUsed":false,"words":"select world goddess scale exist volume next pony kind comfort caution talk filter thing nasty they ladder victory color shallow ask feature leaf wonder","addresses":["WZKbvQYNLrjnhkbEe2iFWZTP1qHBskxpcT","WfnK64bH8Ne5SyQjiB9QLYZxaGs7FU3RYB","WaeGdC8bm1ZaUMU2MJYpfx9LsjiBJjg3Yt","WPdJvED7mA1TCRWKyjNdJdth2rwENNhi4c","We48wjFR5At3qHHg3311EmT1azWhJjhdvP","WRGs9GPPfotGtw6k4aQEJUhj9z2xCpvbGz","Wdzu2U8ih17SVgbC42iYWkC8uuwna1KfTv","WaeZPALAn59zyz4kxMM2PdBjifVWg9KfxJ","WjNYCuLoJboFULEteDNTmGspJ6rrQhktqR","WR8dCCKMHfhHFk9FCPopvanQqaMmH9LtoD","WWysBrFz2Vf91c73qWCSS6yBTgovfdaUhp","WPbKh4yR2vC738dGj1cUVDeqotprcqMQkM","WVyxP84rRkZhBfiQ4n97a5jJxTqr2gcwgo","WiYkQHKMMsk5VEZb9qmA3EhD4AC8z2kWNa","WcYqNvETqiY6Z7B7Qn7PwikuC2t5vbnUVS","WNsyrhkE6QwsqpA45KbavuAhY6VdhgEbLC","WgzQ7piDnZN3dyDz8JFo6WkhHAVUX14jyH","WQBCmMP3viVi3fKnZtrake89k1jRduC7RP","WdxtG9kTTh789we5wVRTkjcpnXXqTxr5ZQ","WQa8EKtMk5RjzE45dwjgg9vzR2ZLAefBfR","WPZwg9taebTVTyJ7YUVFWAcGmsAaUoekvk","WXKNHKhSCb5J4u8QPr9dNbefXPzDv4epXj"]}, +{"isUsed":false,"words":"fiction beyond hospital planet develop maximum crash purity mad shoulder crouch scale develop during lawsuit miss love twelve genre trap slight scissors nerve royal","addresses":["Wau1kr1jHMRXeSzUAzKc66WXppp2ALwdj3","WRw7c7BaxmQnn81WF8nXaz7s3Srieme6zg","Wj5doAPDoUVLiHWToomPmLHuBthYoBTJXQ","WSKFi4hkJgGSEmTfmUQYnvaBHkBko7WjKs","WTMBCT2kTXe3aczf8uhZ48ADP13dcdsTeo","WmFCSiYjSFDkUbN7nx1bHyrNsrcbgUt98t","Wg5e4F8TZysLHEmyhAjHFdA3j1nqDeShQ1","Wcm8Rj38CYpJDNJwAdew7RVFWtg3tC61Pr","WhMJ3y4vDqwj7fxzZSeR4noSSE1WRymb9g","Wcj2LxAM2JX76SCm6qSovR6cgnuELWrusS","WNkrj7EdCCL6nbb1cxhp1u6JNQtVz5k6yx","WU7jiLXWbg8zgM3CmGEAUnxe5Z9MLzjy7k","WXJj11kXAjDFJcHsXD25EEnno8YGchM8ta","WQVxwnBTAKv718DfzXbfXkTAq3DUCGeMLE","WazykdeiZPk2fVd2PyP1eMamtZNr1bhcrv","WVNML5gjDoV363M4Q4cLn8a9v4HyeZmKmA","WQraMwG7qm6Zmu11cCNcy3qJsv6k4mTuuV","WbaazeUvZrN74aoNjmi6xZ6HiyDhHn2wnK","WRZEHWpvhwTV2xyaybGcnWGf2wvv97GHrs","WYD3rw1KjodX2fNJFvF5rxLBNjBCaGKJQR","WViAuFnpzNJ7bT53DcS7CGTCLJHtT3Kqj4","WWNqBNSuyaSNQyaXsnG9QDcMHq2wi1Sp9i"]}, +{"isUsed":false,"words":"general help rely robot future aerobic note lounge pen local aisle broken dentist million struggle state build border when pigeon tank win differ captain","addresses":["WSpwsR2SJe3111a6ouz5f74M7XcLRQ2tyb","WUJ49QJLH5DhF5GbLfpZkY4A5W5gWnEj3s","Wd6xEdKzVm5eGadTXE73exNxskDC7L49Xe","WcUPqjdK9o9MtasVXHNJ8YZN56v2srCA1c","We7vrD6WoLn377ebnw6fRnyZsgtxos8pvj","WR8azHCuGPwQ2usD9ebWsTZKwhiupaj9XU","Wg14wcUgH5Hs5dBTepqHatKDH7LTTSnTr4","WT52a2VrLkvg2wX8XaFdupq9LjaYb6gPaT","WQQUfvUDW7ebCKXPjudUTWxgSbrwVa6nAk","Wc5wbJqSqtRuq1K5pYA45NH3pB4jNs8eCP","WfyGqKf4fQ4F4kcpmEDMytVNojigrpTxDP","WfuhMFpZWuYcXAKbVsLrwA8vTppDr5JaFs","WcrP9Nw4Fako3JTu2W2goMaLj5oWZpRywW","WhEFKD3agXrSYJNJHPyibWTz3oSRw1mRCK","WkD3ePqpsnTopYdyQHhVP1XsYTC8LmuzNF","WfREViokP3ZUJY1RKRKXtferVe8A8WypWZ","WgMBYyE9bAqrKacYeZxRuywJGoPPvsPhcR","Wmb3BbpgY5eL4VteBKnSjisg9M8iNNVPvY","WhGAqDrDLimQHMwEYXF1XBPRe7LnTm2Zbg","WQnhEFEW6RKeADhmcMumCn9RpDViEktZnV","WQDrNxppJSJ61RhqAEKhVGKrAA6Xs66DQn","WZCY3j75uSxZWbpFAu2mVarNqLoV4h9kcq"]}, +{"isUsed":false,"words":"hundred feel census mimic brief rich harbor worry jelly benefit soup skate very beef soul file slice rail grit ill dry undo north pull","addresses":["Wmp696mcxcRxzTehnm5e9uXMsXWWfSfbd6","WY72WKxxZw1gbjAFfPMdviQxQvgCxNSgao","WUJYYuoJ7r1j43JH1QVfyk4T7FQCwWw3yQ","WUT45K5v1JbUeHjsBGBeeEzJbLNcjFYRUi","WRrcQ6yPjkZgsQbBZkzNXo3qp4pCaxQYeB","Wgv84Q9jQsmNBY45Pn7jRmWJEKfdKnmyrP","WcGdauc293GqxFJ1trBPHathQNPvj2v822","WVBHjGCKC24ZDoyEDUFd1cssaRQgDAskgC","WWwWjtzgcLiWqUEcDCZxxeX3cDCYa6de5o","WQ1duKZZuFzfuC4toRnc3b6k93XoWRaU7A","WYYRUqQgnzZ5D8zC9XP48GfJWPdkTEsCHJ","WTUHNCyrPeNEeFNhWNtf3LvvUd2WV5rX65","WZuiSwM3E1oHo4PW78qZKzPR8oQ3gy9SGQ","Wh9zx9KPzW9AerSQEibftobepQiPirqpzj","WWjEsv5xRJ2vkrvt7eFt7Xzbaga4Kuw6rD","WeK4diy88FX2VgejFbpbhv39tiBSj3H5cv","Wbd38qb5L56scQtxoCP5aUuHSb6cLmEveE","Wb9CZQ5FE2pz3Dj5idrri7s7m494Fze15M","WVNbigktepxDBkSsKrxfP9XwM5qKbKfvBW","WehWJb13jTKAcT5AD7RYoekCw6vJzK1Fw7","WdE8XStcitmM3vNpabZ6qN97BfCHQDccjZ","WZRcc3exocaxwgBqqMRTztQsbLbMqPX3RN"]}, +{"isUsed":false,"words":"humble theme marriage perfect sphere edit pause muscle level type wash animal piano media truth into meadow jewel addict hub style fame clerk today","addresses":["WTcYqpERTeCtggcygEUpaxbGxcmACjinfi","WY27GKVtBwSRgU7FDJpYcnfiW6BzPc9ovu","WizPcNP94ptoZMQHALM9eE9hxBzjD36VeE","Wm3Cjwa8LE7YjyreHvDc4xjUYZ5Fq627Zr","WU7zPJMBMUtsmrWC8PYLLqYd5e3RpsND8F","WarhjgSUpeF3AV2phhy7sPd6mU2bTrj5sY","WcNUEyRbg6Swr4FQZi5v6YPt4gwduLKZAt","WjdbAth2xpUuWXvwfv8NkfQmYh3B7vj8Pi","WSpCqoZdDTvvUvn6euRRdLYQvw2y5n2Wpo","WVbWytkr7XGYpjioMvprMRAC24SeYumCec","WjyfNx5ACALcr9ycUDaDJ3zXqBBsVw5S1u","WkZ1LkbaCMNTuJcNCFstYheoJghVjVR2Sz","WfBN7eKB66fe3YCku6z84RHWqVWE79MFNW","WTuoHTYMSx2YEcbaCC6y431T6GXhUuGEFj","WRsGqJBYTfjZ6w46ZGsW9G2nSbCU4b3uXU","Wbz7NyiQ949xA3e6uA5hdJxujGUuNeDHcs","WjsoinbA5FV9UNMYQrFGFu1wNG34mQ33eG","WWtCqUM6utwnSswZfddZ8MibeWrPbAaNGt","WXP4EG2jPuwKLr6wXvE3jZpn46Nh4e4BR2","WWifzN2dTPpAKzva7Drd41Fyre35N3ZYAr","WecaTCUeJs8MwpT7B4AHVSnw7WUTRP5nxc","Wgu3NbtwCuiJuoLhWvQ5heVaUJqr4ShDT6"]}, +{"isUsed":false,"words":"furnace script boring index rubber blur movie asset flavor draw cup fiction income quote warm net toy wrap guess alone skin media fabric special","addresses":["WhLaqKiM72fgLWDWAqr4EnPjrYXKqEjYif","Weu4CJ546jvdaFYrD4QYSKiPPix7mJFt2s","Wc54vrCGEfMxpaEr56VgWZX6keuJQj559Z","WikHBMbjH6KqGmXcQohzE8vFT2wiB1jgSq","WhXYEu69AkKB2rrTvcbUac33HsFoyrYRdB","WbF3cD5RPUXfmy8hGSb7wuCB41SAApLwtY","WdWyLHbMDVREfn85EHe9gqyf9q9v4QnECr","WhMHcmSSJj87ydMCuWrmSk271yMipfund6","Wc6wbmcGMMzZ93k5PXHVw84zVjFRkQu7PR","Wb6jrsragUSuxs8F2NDfivFjbxQnSycRWN","Wawjrt8ze8wUR7b8UMHJ423EzW1F6ac329","WSAEM74SYhdACf1w8Gn75ngVXXbXNjqdz2","WVRApwrkuRykrqx9CePpb9PN4cdmedHb3r","Wf5qWaJhfbAr6EB2gC82qXNzSsndLEDJzH","WUWscaoy8PSnctKvv5wifBZvdT7wQQsjdA","WYahSRzLMN2QFkxoEMMVbGdrF21kjCpsqt","WaCA4oBJv89ie6sQg4FfPY7eG713WHfQb4","WmmQTd8qBpBrzsrLSStgpwRvUdJLeLLWHG","WXYWnkmetdc16SB7nWsG4m1HhGc8e4USgh","WS9rQksg3uUvkufNPdGaxrSMfersspJ3Af","WXzTuE3QmPKTi32Z12qSbVEPQmvj4EyYKv","Wb8RCWskRgnwgaJNJb6YifpccmqRBusnh4"]}, +{"isUsed":false,"words":"glide before skirt team stock unaware taste crater kit youth oil maid decorate cement pepper provide dove syrup capable front fix consider horse enforce","addresses":["WhV6Whi8GKzunAMBvQg6xQHJ6nriB5M3yE","WWhVi2oUqn3TTQ4EBYarvAosax3yWsU8MJ","WQDefq5cH7ehGniLVpGAzbNQ7SK26ihE1A","WYCB5dnz8zvKCVVWRmNKrWELTM6nJ7CoYr","WURHE6LtF2cjq49fCpE6JNi3xDxMQGWEXe","Wih92jgsNVadT4FrBTYEWrPSsgWL8VWWYk","WQhyAsCy9JTFXwMH4qekVcoin1d7pkG6fi","Wczu325gEz2djQoCDr9u26rAXYdUtCWFWw","WgmSs1QdqoRx3mD5gLThZyRnMdkQSK6wEY","WXMf9zk1ajc5euocHXBC1yofKtim1w25mr","WYcoxiofPSnajTJU6mjomm1VEMTjkhx7BM","WkwLEh6JNX1vBPU9qUNcJJBoM1fNDJPJYD","WVastsEJiP7jTwyarXc5y8z2YFRy7shULp","WQHvrG7t6hpzk8uKbHXiD8zNFSYZ7E3isZ","We8FZRMFMiCGDT2vy1uS8Epb34GDkNCsyw","WmP4MZRoCYcWZ4gghF8mNievvxe1rEwVrW","WmEUxDHQHC6nTJWkNDq2J52zscEdF3BWn1","WZjnvUNimeNPYjw2vqkzoGD6YvDWyAQRsy","WbfMVaBwoFfFKxpAW91dyCvquCArce6LPH","WSRDVBdJwXxgVHM9UbznnzfLbXucvTG4i4","WT7zECQ7jWGxFgjNsTmhqAhW6nhAXuBKbf","WV6MAuctHpWdab32PSdh4hmfvAinDQYiHr"]}, +{"isUsed":false,"words":"alter meat sick method tuna inch bargain coral dolphin cabbage bring pilot castle iron voice scrap wild glare ribbon beef come okay busy put","addresses":["WPAnTjymDmPG84Vx2qhrZihS4FQ58aaPct","WeSeziuyiXVsikcP31csuvTtzf8codj7XE","WRzgd7jeYrYTQJTnio7JA5CigLt1dQj6Z6","WaD7mfTfUewsSoLLzwhstwsdiEh72sSmvQ","WVeWfipAPC23dTbSr7TzMZEDk2KjkXzzBf","WQH4ocxRbnMA6cur2CfSu4iUpW2mSyJMoT","WhuwFBwR6bjB1JkH9B4XBZxgUPsn9bywKY","WWEdqP32WGdtuBuVPnodPF8KDkh2YFomC8","WY1iQjjnGaqfUQmQLRkibKZfrQo5iFnJWZ","WSbna1uNtxJbZKmdo2hHW41w5QiYSCKZqy","WZP1865D9fBKth9w8958kbyG4TH7pVMugP","Wj5gkHWL6j7FqMNB2r9HAFVrfDEt8MAFLf","WizB1v9rjG18XkfLFDopc8qbKHD7S1YZxJ","WTuX7XYhqnvk3F2o9zfpV2Y9S3wBgDuDU3","WNnqBuTuYzAfYTVs6tX8ADF7VpiXNpUVSZ","WgysbC1TZNQqKmn3CUATt8r38V5Ci86So9","WZPfTvLbV9RMPiuPfEvMAvzTfamCk1wxbJ","WThNzeNL58c4NMbosFW9C6SUsUpnkM4eBM","WRpoySaqPLhNe8AHEchJ2PnRApDSkYjCx9","WSpmvg1hL8Zvra27hAci2KehSdCmcnvm1P","WYTU2xqXw5155GANSTvYA66akAyr9vVtWj","WmXmVggDkC5VkyQYGAqnSGtNU6qRkUJPMw"]}, +{"isUsed":false,"words":"income milk expand thumb october audit result correct cherry prevent away slide junior excite cattle marble fruit apart where tell october design trouble lion","addresses":["WPysGHGwRvzWEry5oycMjZUPuWg4WnPf2z","WfkWRMb49oFVaChp3U5yvjC4Nk1hqb8Tai","WXjCxoyucC51fpxbmwUwABArFHRysDf4Hd","WT2x2q2mFAx45xg4XjnxxNXiy7AmNz4pwe","WcsqkzjcttiF2hZJ3HniEGPSqbWfvzhMJm","WeZ1DjNbRmM6ivcNmz2TrK4bATjfXMTMeW","WSpuQNKU1oysXZ6Qd5XQfDU3YMFXwfaQA1","Wd3oFjgREiKrze7zg4aDg7RE7gKGRRoAU6","WQj4vGmmFHjdGUMNEXFjCcLeFRoi6yQ3Ea","WdrvUWJacX8u4KrUCYQEcTr8GZe4wqB6MF","Wj1jbvmCEiVmH9QwVjCm1VfxrjVDtkmQvW","WXFkeSKqfLF7RHJWvThiCX7WMMgKTK3Ck3","WcbGH4QvASk59QTZaunjhRjJUyWNGEnPfD","We95KnUKWf8kAk363yDSYhjtS4bHUcGwT8","WPhw1ZUXt8LRbHZkd6s1PWxkdNdTZpLJNB","WjkteZ1mnkFLFqBWYVhicWTDUv6vpzMfDm","WkAUnQMvJnmgbpVM2QLLVbrEFYXqXfgWtq","WYpqYnxDwxh6Rn2P4XHwKUitGkHCsK4L3g","Wj7QVHtyeBXpahemUvH6HSxKTJbr5XJcUf","WVZepU4MgjLJMc3iMjei4NNpe9r1xhfJ4K","WSgRKsWqD79FVhm1d9FFC2sUDq7CWwrYGw","WhzdMs61nT5BrX8gudQK4ha3fkFts1v5Ko"]}, +{"isUsed":false,"words":"around tape double great ensure cash hair pride wrist state machine unique control accident gift upper else mad interest cruel unable right struggle penalty","addresses":["WPCShngA45oJWjyMsx8ScDuHCyN3PyEwbd","WQzvQ1bDrYheFmdMGwMfLVzXp14J9w1KbW","WSiLvC1LRYxXceewvXMhC3o9vLbaWi6WqH","WjR39uZZFaDcq57BgK6KL39CgVjjY6Frjh","WZgG9MQ88Q4tztakHrc47Wc5sMa3ogaY9J","WgFvBCpSyPNK4sE1wa8FtXqBLmFg6Dwxcf","WTznwLJKQHrjMs2Essj3tFUNbDFd8v8Jfw","WjXtJYXRRcPsmtBBPiSuLvEJs3QdcHNJWz","WUPB4rBCNooKHtc4qprT87ndCj9WCKb1vZ","WhmgAA1KS6UfUgN3LAELgNQjEJFv5xPRJP","WkQWPF8zPN3RzmpMGDF9wRJ3MZW9H1TQdR","Wi42LaW6tskD5ZVUnmp2Zemqn1oZUoxP3T","WcaFMGUW66egBN7xTijx57aYyhtUyApKTu","Wk63xcJy3hvvymhw65jdwzaFnB7pPNXV9P","WXUMSt7E6yJyJN6RcFgZpqxGnwvE6DSdfh","WRLUEKR4uEM9K73zCLFh2KoCzo1Ae2i53C","Wid4JRseyXTjUpcjZ1uxyhiVczuddkzNCK","WkYMEcbxz4N6ArAQ7Wu4R42CqzoMNm2jJd","WVfhekwfCeGXY9owpHVnxK86yoSV8DUBxt","WSFMHG6wd1YhLfnzsw9PAAFw1wvT9NBQrP","WbXyeWoSL8dwhsy4RYq8J5mg9uBcQYThWX","WXZMWpAWN1SVm6RZaL4oUPg93omo8tWvV6"]}, +{"isUsed":false,"words":"wash small badge divide save lava repair mystery drill clap boss knife advice topple suspect brown delay lazy mystery rabbit purity float blue artist","addresses":["WYdfgTBExkT7DBp9tXKm958LLr1ydeoKTc","Wc9AFg6EpGcqioQAZikc2UHjeCgt3wGx2a","WbjJN9Wa9DSqrqZGW6SwfdDSatAC5Hb6RA","WhLCn22HaRUCMy1QTSEjSeWzdpxBafHSYX","WZRxMXVBMvkW5qpahzGJGEew6nDrRKTNjZ","WTsdCjthQ6KhosfaVMjpy7VHv1gcDi38bY","WVUAfcjdZFtqF5EuXoJbYqFBR7EnNhcT5r","WTmAt2dFQnJjPzLCN5xzgrpwAVTA7DYXoD","WPG2gbATgbyDBv5NiuLpktQqUi2DuudAUP","WZ9aRoz2E7dEjqbkr6eYQtGhmykUxyTVM5","WWQ553rvtbUZJJJbwoj8csp6BtM2y486F4","WWe8tnztjf8KwXbAR8BZUoKJSAAb1HuEUD","WUfAWWRHKcaqQmQuAtwkg7Yf6KJtWjZZGt","WdCF3t5MsdbXAfZDY7QxT8qV2WyZr53sU1","WhTqAGeg6wjEU7ZsA7HhwwUdGeWYCXb8oa","WmunpjVFpFxsskXrJpSHmBdreBTBYVTfzF","WRjG6yvsuBUYmWERSAnimQoUMmEP1aFmxx","WZ6dma365qDpEMCaGAgBZzB2NCaKp2pst8","WZxH4GGdX9jWubw7geQRGtfKyLaSkjNTpy","WUk71GbAuYdhwzDXCkW9UAzoeuXDq3cJkj","Waw2wSkHFtaKtDWo36Fe5FZLQnf4DoBVDg","Wapg1WVuRb8b2CFxUb3b6Z8c6JbnLjEYpJ"]}, +{"isUsed":false,"words":"scare rate left border angry hockey arena invest elbow napkin sun gravity armed volcano clay afraid flip inspire hold theory company useful ask grape","addresses":["WfNSn4xXAXiZaQHKXiLvqsdTqjfoRBkKgj","WVVWfn9Mi66PgsfRrm1837Hbihy3QjdW2s","WcpUyCBqZWyJUhLdbrrhvkjfTNAn1Udkzo","WfXg1TZTWFbPPcicH5YGUJfU65BLLQ82Gd","WmfKgsLUY6XDimgkzAtG4R2GwrBTmrp9ZJ","WcMTPV73LsD3PSP56UwwVdzv8xFpgLMmqT","WawwFuoBie9U9sC7EiRy2sYzo3GRJswwuY","WSoU4HGK7y3m6CrYJeQX4xmFuyuWfV6tmC","WUoLXKTF34W8eFcrdo2wxvFaXXuLDmdD36","WV71qdQnrzkF1VEAuE6d3jDzEg2ksLLqcW","WkzvDnij2W1KfhFzhpnHc9tqvqf3AqMfAu","WYuDKJdGTA5zprPKGQq6rHvcYvsakJrj3Z","WUhzgB52ceo3QSGUuBg1siBsnZ85oETwgD","Wj2CcTMva9N55iHxPrtrBLMAAhFyaWi9rp","Wgs3uFTL9whLExrsBoaHFV1pkbhaxW9ign","Wgj2JS1i3RNXpvboE87oKQYGfWoK1asFnH","WfMvgb1peezjC5iQgPAacgrfUJmMR5YtqE","WduwDbhmoR9R99zTxXd3tF5KNvinYLTE9Y","WTY4gjdJMoMCuthHpNibYPnwxMBi5rvFuJ","WkU13wxFNyEPmeSyGjprj12NgH4zXAsvmW","WVs2RzSDPE5fx6xpwj8baAtmX9qzCxPqHT","WVGoYTdppnm4uZ8uBhB16uWHSN9AYX81UW"]}, +{"isUsed":false,"words":"craft mushroom kiwi siren fly canal grow typical light boring scissors state auction green poem surround mule moral type tunnel sunny divorce genre undo","addresses":["Wfxq3eyaS312vuQT7DHMZmmd9m5KT32P22","WbYMNQYR5zgnn6JeLn3WtNhmmUcaNvMXfy","WTfhtiWc4RFvKFu8H92NZQtjLiS2xhMBWn","WYyZ23yY3w7CZVZK9pLwEt2sh4eNTMeVvz","WgsjLAmJJLBbR3YTSq2Mj4h43vmMkgNupb","WVpiW1TcqYjMggyuP3Ctt6F2taCPhjfrVT","WcfMFN1hMsuCeo3dunX2hojJaokmwr1UZa","WYHgXYdGsi4df6E4bAdHkzLxTXSAbjWauh","WNwxp7po5zZHQ54fyyP858HutWnbDfyfX4","WYW39mVueNpEwuNbqgx81XztahAGUpZ8PG","WdmkhWtRWs3xCsCyfZiE7WhcVGPhfvo34z","WZqnhmBvs628VLCYGFb3RB1BpxJjYZGABE","WWgeFa2VW4WS5C9YdvP8jfjMgbpaksfHVK","WSLHxLdhPiVWhyvrNmqoAouPPKCg69dz4B","Wk78dF15wod46Y2HQkKzVNhR9ek6pwmtMp","WmZiTDPLJXmpnd7jKNvgr9xADqwLJTVj7V","WRL7UbhBbnSmMBQmiAiLiraFxouXyZzPzr","WcRfoXqFRDtNAq82n9aFtMNbtjgLuXYBuW","WiTXTdtWHXoHtEBeJvtXGQWnu1osWwhyUj","WVwekHdkujFZLxYQScrWkJ8c4ynNXf9Vx5","WkJDNGn7PHjFX8q91McAQJfjoQz2ai5s7m","Wc2EE56kNiYYV5Xj1P8iaZVm54yihcHbAY"]}, +{"isUsed":false,"words":"tennis cheese raccoon curious blind clerk dentist subject unknown problem negative federal review member pride render you define two smile mansion key fade fabric","addresses":["WXQCEkQCwmhJCFW23enRyTGU249TvxbwL7","WVYcuR3B511Tb8cHmYznPR4vP3BVnKB73o","WcNdDqjP2ExRQ9Cep1b82hfmjWB9X9gjNB","WcvLkyuBDWnhJTcFdQ8WeTj7hi5aa6DUkk","WdMPk95yETEJo9iTgP7ZAoZ8rCmWN7L8rS","WcBfL41feQxeMqHhmUwLwUNoGHXXBW2EPp","WWm4tpvnmqtCZ6W74cCA1eQTx3Yc64gdWn","Wea5x3BwAMH8zMLVZW3rfPd71GYCQExi2K","WcaDtEM2211bNNF7uxWhRXkuH5S4RWWojD","WhCGRRqimtW4DaLfzoRAYqFNnZ5T6QfRCw","WikmXinoFHgBiFcpBfh4J8JE2sAtrcvai8","WStE2kWaYvCsGii2n8YNbPbd8x4rcag1Ji","Weyo7v2dbRy9Tc94FANqwNhq1g9cSSmUnv","WaKaCzZxtH13yCQrfHyw8pqNPNMHJEQvT6","WYCJcRiyYfZixe9K415Qm3JEDymgLxJQWL","WVYsXVReoxazXLMfmeqEZWkq8jqTLJt8oU","WgNVKDiiYcse4dsbhRBMauQJCtrWhMzsjk","Wi9r5Sbyxz3Xe3EgWjPunQv2XeCzq7hsH6","WXnZawFzNGeVuXw3TJddMdJwLnGXbjGFWc","WepsJFzABU4ZC4UzGNGVQ9mK77t2xLmhGg","Whh3nwvdkoq3LAAMKU4nehVH7Aa7u6pnit","WiHpRJFVz7mXeKL6eMdppeVPRfeg4cWhb8"]}, +{"isUsed":false,"words":"install taste drama human option cave keep unlock daring fuel crunch mention garage number enough limb zebra toilet scatter base two grab discover vendor","addresses":["WiWnBz9xh1P9ENHnA1KFrNaSReT55qv87p","Whzuxe3yzjKXqDaa2cnvG1rQYpA32Nr67U","WmaY7i2rioN5mxaJWxYEeUVG83FwP3iKW9","WPG9Y1jihwZJzVYrmNnVyxo4qKWgpxocSn","WUuPjo9Em4mApEJnd6yx9oePZxyKma9uow","Wc8M3qVn5hZ7Yj9UWYcRkYfeBRs7XXRUY6","Wjye3sQX16fzH4Vy2ec3LsZE1MFQkFa2es","WQioPKGWydq3CieJRPeq2YN5Hsah6pLZHf","Wk6xBHkYeA4isupNeUJGVC2PDQX9yZNENX","WR9Z1ZE1hgmz1K97viszizTFLXQgPoYheF","WXdWyH1dxtTfgQ1QTaZrNZJbVTE5fPdRZN","WfeuGbM9vEExSKrVELPds6RmfpDZvsW8TD","WUoa5WxWGfnkdJFLKmm3sB5GJVpcVxmYxY","WbkWCzAMgPQyeMkE5erAhckBMXuQpvMbzt","WeP3oNQbTWzgaGh9285zua7zigqkj25nRd","WkBqgBf8vF32x11XZNaJiiygRFnG279Kbn","WYFpSv5MaJvVfcLBgMJbyPnu34Q8ac6tRm","WhvULPwBAY85mRVyBTx9YANL2unGmCJKCh","WjySyWDb1KfRPjuQgkWxocou2DNu8mGMYn","WWQeExfteX1dBqxi2qgzvEFWJu2rqy8PJx","WSeYt73SQRBAvSFNQdvAE3unHDvKE7uz77","WXwJ57ryraJGpCMZHkaHAxMeVooBjyf8dL"]}, +{"isUsed":false,"words":"dust critic label lounge private pottery pudding trust ship portion sister little assault expire piano ritual collect woman asthma question injury hobby buzz mechanic","addresses":["Wch6Q1eb54Enj62rUj7ULhMEu8oqqFtvKw","WT2ZjYczphGEuT7wLH71h2QjfxUbVcHvNK","WiYjWj3CaHZNRXzpaoZpWH9pKWkB8vtUqw","WPErmdeGn7zMoGaHDgiaaYxJdx5fPx6vff","WfA6bBUuAwBCQeuiUVyJmvZbNqxWoH5UhE","WUXUHmL3rNFZ6WgvJntPRtCo8M61CRrQ6Z","Wb5QdypN7FNtZ4s3MNvJry3qwuuhKQ9Dk2","WQmvvnNVn1kGVxn22vtGj1ua7pdDFeArZp","WSJhFD3xZZ2Nm8fTNhLbTumMPqD147Zd9a","WbDKa2UrVa3QPbePSsq2Na9DLghTkua7Hm","WZLr958Rh59aSbELq1JmYxsmCotuTXYKw2","WY6mMDsxGRe8TY9BpKFdt8t4AwdHLsnTUs","WehEoLy4vZatGXzBQYhNJLfrUUV2g9TcQw","WczVLKn6YEjFqKp5stEFpEpC45hWP688Dv","WU6C4VyER5ToSCGLSQ7cdBpUVdEaaeVrLN","WckCiYe3indBwUkr1KFAkBJZdRVzfrRqhw","WWrejWDk8yx1Uryeedr1yrb1XNHLjnCLzZ","WkYUK4UbRH36apMxPCJhBAKcGM4VnhbRVB","WezyA3ekNWZSbiGhcP88ZC4QLXmULbieHG","WhDqF5pidKsaGjFAqtmCdTQvoLn46NPWin","WbnUgozUCcUtHoHSEoumDtQAEXuUCoiCy9","WYt9TfYhkfFsA7XPSirz6Tio4wLgzhp2n5"]}, +{"isUsed":false,"words":"cash access volume act legal tide humor volume awkward domain adapt quiz judge poet ranch denial arch giraffe about dilemma term robust ride expand","addresses":["Wf4ctKvFR7iTdzeHjhnsKmFRW11G52MbL7","Wb1P5kxWtAY841nEE3BXErfHjmVpJuGbTE","WiRHiTB41QYsCpMSo4Atb597CZv1gWL6mv","WkYNN4UBhSfu9Yz829GkJ9qqi3StTcetR3","WkWbt934CdTDfrAKM17mSU9Rkeu1ttUhni","WhCfJVtNZhnXEFBbWGvNEPqhfg71NxMLNN","WZtcNyNLK6yYCadqSWAoFXVEz1yoqrtbHe","WkqiiK57ve2Z6vsjaMvFVjkaTWrKijhPpc","WU4HzHvFSrvEAKWA6tdx3U8F3KdvPwoJ79","WdCZpvUREL85habu1scEd3HNzaQ6gANqd6","WTEJCoLto5YML3968FTtiQq4uqDCKRmBkd","WZx5SFCsLJ67zdfVxJtueFTq3R6RSeuvPM","WWuDWw6W2RUpwDvEwAkRzaKYZBr8zycaij","WbP9532ucKowkRSeprCujrSQgWZCAE5uby","WiFksCHp36rXDuzwJhwzDvyWWfyAn4UzSU","WbJ7iXemEXYrjzMjYWAbQp7X8ystC1zLuT","WPoQ8iLC524tzrkkGB1mthHsXu3qGJGnHR","WRCC9Ndqj9nmGjVgKJRtBQKPXVv83BuEev","WZ1fi3wra3gQ31jfJ4rH92vCGRJcZHidYk","WkG93rAwNDpAra2qUEDtCTafEHj3BAk12v","WNnEP1eUWeTXBqwsqvBFWEfqDbDXf3niJQ","WgNFBZVLco6PByBXPV5pGGVwp8Ag1Eicjh"]}, +{"isUsed":false,"words":"goddess host person garden filter drop undo science walnut shy iron joy useless core solve weapon parent orphan achieve unaware polar hurdle trim tower","addresses":["WbbMwbuXgftDwtG8CpHe3hzHm4n4QKyEUb","WePimCEKRrSkjSXMWbSNPKT7YoXPnLxGNB","Wi2C5i1wPmzgRoDZCXQZ5E2tfErKVqnswm","WdUMrXfSYYqKfX3qbFMYtfK91B3eYnSHW1","WUxgG1r4YQRC9LdgnQw8JqXUnMiBjXbyDG","WbRN1ZnWmxZ142g2Xpmm8pAh7Ap4VTSKKE","WmWdygC9Zcx1oxmxwFYqzSwifyCPmS7GBC","WgrDANh958S8YHMzvVc1D8axvsCUgmn8nS","WVWgwC16QxkgArSVYGJecZCNvDkK1o6Ffj","WWMHvDsBSoVGSv8aVHVQFDUXyAuNoiUgs3","Wjy4W8fA53KtGA6ThocPevH2jc3XwPfCoH","WaEqHnYJtDGR733gzV2rfLw1eJqv3XexEA","WXibDxP8yaSkyPykYXPx53fMEBKPpnh4b7","WirDUP1qTiduHfVFhzkh1QdNJs6vm1oBSC","Wg6faBDaP6H9YmbgFnPcsutsMRXTUVqeUz","WknYjSfxre8SfrRQNuhMFH5ZLv2C76efYV","Wf4uvr4M1daJjKKSqN5dyovB7FnF4KqGq9","WgQdAVkcJBZ6HGWXaaeGVvxZ1gKstsGtu6","WUQy1UCXTaMBpt1MqXTZRKgJKpwnc99XwU","Wj99uVDrZB5gZtaXPEewKaoJBXWLpMES7t","WRoRt7NGLqVf9c9XevHaWNmA1CugQXVDtU","WmnYaMh9aSAhLHgZ1FRFaw2bbgFHTSvURd"]}, +{"isUsed":false,"words":"reject patch distance divorce exit marine credit spoil admit year mix result release close stable ozone weekend elder rude hamster pudding sunset deal rebuild","addresses":["WTaDbj4beXgauRW2qXkMEqjeH4hNrogGwg","Wm3rqThUzsrSgELeQs8ZUBJVmeW3MLBQki","WSqtG52o8w3eBGz8LEfzFXr9DwwGWSb3VE","Wck3pUqKW29sX3fo9X1mgquMzQnfQC9gAR","Wj7WBujiQwFyndtC7yrquPyZm4gMfW83E5","WcAg2fWXpa7FkB8m1hAKM9Qry7oRWVfyEc","Wepr7VqoSE6mLDcR27VPYfSRujyFeCzxgy","WRCGtmk2DGJGcBhZpW5uDY9WpMyxNC38gr","WS8Px5sDYp4mTET6cCt2qxydQydRvtUaGS","WSz4tccnUEjLT7q9CRXSgfLtAhSfZG9saQ","WYGUgAnsAKHavFgnoCfSuHy9HYKXDb7Xiq","WXMsNVrYojyS9Ya4wwbmYAdsKhq7oVpsxc","WhLvkBTPfspxhFJyWnfipJwp5XXDm5JzDZ","WQ9Wf2k2FxKgzo3j5Rm8e8DGKiyTeosRLW","WR96NeK7fZkdKYUcSppDoq4BUsZCRZpF5Y","WeGhXjf4WFDoXPFkhvPsTGW64FofP2uY97","WZATs24BbKiXytLjGs5qEq9FPRxDU8keAe","WXQ24XE2HnUnLTtQwnS2qbXCScLmgnTg6o","WQCTy94PD4oDsXcRDLEbShnLYC6zrBgQdj","WgXzV1uHoeYkSTAiSqQEPi3kAW6KV1aJAF","WNwEeXMHzcRwC6aPiwLxC5HFBeGCqFgKwd","WXJxSaFeMSmkiLM36j1aRe8kFRsjzTfAmQ"]}, +{"isUsed":false,"words":"turn jump card float pull ball army wreck love excite viable modify bracket regular error scorpion pluck grant vital segment style sibling interest yellow","addresses":["WQDv1KWEFKECvz2oN2vQb9dhbaHJmA4yUj","WdpR2Dk6HSdPTai4Lq2tbYFLLiPEBgSFt3","WXhEDrDt1456V9uX6BEpPdUoANJ3wF8uvt","Wk3HsmrcteCDb1D8fdFfPuFUVxVHTBFNYS","WiYzy52ET9AtBvYzfmqonmNR9Q5xVBW3nz","WdXgBT7jxCUbvFiT3nu6o2zshMEDS2npZ8","WfSrYoi1DcUkTzsoDrx4L5yHxN8GTv4FQj","WkpDq1QtxFdDDubykvp9ZxKcUxTzkVeuv7","WSrFVDi4g3qDvASEW7NitKC3WWNc5n9yzN","WifGV64YuFTnbayLEeTtEvup2BUJeAGQTK","WeyYS9TyyrQh6wqD1WSKkoyxBNwqL9jq7e","Waiib4fjsnNvjMVzoV7g9Bsm3PNompo4ag","WfunwR7Foi8SripnBUnjgLhpHE25dC8HBD","Wd6jayjzH1hv426HP9DqttFc5V345frymF","WdGMnsMT2dvFUwzVi5Acvp6RbTySHxwCft","WhMtjCabdQUUzCwu5FhRdxaU6JACyJo8BX","WY5HoqyfgFpbvg54UyKNArV7LPqyGcifzq","WQhWitPkVKm9TY6dEJVFE8CCANNGcUt4ks","WhhxXbKZWBWezPc6Fpwc7HieP7UPePcGc2","Wg5HjasnrxKpoU8MndwPYZ39zbqG2nvdKk","WgLKkA2fehxbPP2pqePTVb7T4dbN53PgHK","WhKieaZ6kssQjd2S84mrGzZkGvh6HD5cb9"]}, +{"isUsed":false,"words":"skate base best bone float column whisper oyster license upset odor obvious crash apology warrior hazard summer absent hip clay purse coin lab spy","addresses":["WYNbFm6Pt1upHT8BKLg4kwizrRMAFXrvpi","WiCwi4W2bwVdpksCjr4WgqQDS8B8WVZ6ju","WcsdfuTCzyJ2um16kM9MBrb5hgZJrnmi3r","WhxZZYyLXzjsLmLEZmSCJWZAXbLdL5ednm","WSPFM4uZtPR3NKzDXWircqCN8BdozHaiJB","WVPHNtvronJeoALydyXykUnPqcCTrG8Wkk","WT9Xm5HpGqGQMcsVJBvYe7ZjQAL1EoKwHK","WaRiHPZrz3QHbn68c5DfvZhTPkBg14eXyD","WgCpcm3PqY5Bpdr74djGdrz3pivey4Taaq","WfWK4Eo464pQRhi5XiTFAqdEQzWZZXiEun","WaQAgbwakQhGVSDznZPNnA2Tik89EPWSwj","WTCVmSmnz71ygPCLm9tarEUaQuJKd9yF1o","WToGww8W5pEzgXFnaVs1UtCTWQwJa8ZHbZ","WWr4pf7mDdUB1Xfyxb8XHhdF7Ry8zp7WF2","WbucjoCMAhfAzbftqj8e3ppuhQ87QkG3rV","WUMtwJM6zePrem22HS5XEXsFKekZCfFg2s","WXER8iBsT7cQpMxxTxU3TYFx7ivMkmMtGV","WWZhXh4Qf7BxmvP4GB59Pg9wy3Nu47NQgD","WNqyLmCju8erq6Du1yA8AawM3Z2QNrCEBa","WimWqpKx3mQ7zoxrFAiyi76F1rxUjaewJg","WWdpjTubXe9Bua8VjiC3r3RRXC431f3vJm","Wib2f7AWRa9VkzfxCFRdBRbikmBXV1j7Ma"]}, +{"isUsed":false,"words":"net pig few path puzzle shift employ dutch afraid retire uniform stable smoke airport divert behave hub swamp tunnel citizen soft wall silly wolf","addresses":["WXMSUcmEmVntKDkqbwGP5mZfnutFqBrVbj","WaFMJvAKzp4CRp8Uxbqw8be85MoRbF8r7x","WfCFBS3vSNzGy9ZeuZYY7sP47VyF94SSpa","WUN3jwiegaP3BMEjtCMWXhArxNierkUCPi","WbmiN1Ua3rwEwFSvhvBt9r3cJDdXJbaNGQ","WRSzobKAXobQk8L3aEUeLBn2HiAWAcvisR","WhtJExfd4ggJyHaHcgK8ZQR2iFvTB8Xoai","Whu7RWEobTeXpeKvGbiwaYCBvkMzCWkFA9","Wmig2UtPY8WWFp8YFGTRtfpqQXDTtn28sk","WbBwFeZGqFSJGwTgwAdwh9zzKfs4JUtjgo","WVTdvC4QY52oQHM7VwHWJwa6CVuFj17wrY","Wgdr3ZGTMbEdpYguwmoUWjox8TM3zY47oz","WUyFUG2qp9mct9hN8nTLzpToZhcXRaRnoD","WhksPPBJfwx4gqzcpVcTbKbRsR9sdHAYQH","WgHrz952ZXxLD6aUANf4QuSUbfWBXRb7j1","WYbD6WE9MwhWHb7rf3ebFd6buTofuyW2V8","WdWP7tdCtmB4AeMLoJpW9X9SY7pWB5aU2M","WUzC1ZMs8nPth7awEYq2UZ9oXteHm5a9sP","WZddHNuNrx2WVPk9yCwFpWbjEZ4td3YaDx","Wh9hyeDVWNCxof8Wg7THv1EAmUZEAH5hUu","WagBDh3qCZEgmN8xHGnhBYLACaR5Gwzri2","WeMYTzUzk3C5GS6SnZn1Jf8muM8tUsA5ZZ"]}, +{"isUsed":false,"words":"leave idle buzz engage reward fly answer kit destroy baby kiwi vast own vault accident squeeze inherit scare wild lumber rebuild dynamic birth fragile","addresses":["WPiaDqyDckfTcqZyX9Q9aKud5BUvky6ZmU","WhCo4CpjeMbJYdy52SwcvBR6iZUAQjCcNY","WfMgymNxsJrx2bZWkySsWUXSbb4De2gtKT","WSFMRyn9E4iJNLriPfRqt6swrZMjxyvjCb","WPUjmMTHNWyJxWFQogHuZaGD6niRUpgqQY","WWCXPNny768h3cGDmcNZMSv84XVsh4MDkg","Wdstya8CsHPxr9kSs8115ez9YnyY8LFg5m","WcVfhegcaE2JBik1JK18BRF7ydTWewkBbi","WmsTvzCUAQmR5uS3qGUvGD37m4ew1ed9N7","WUamwj4RRAZiFYv7EELaaVkBNVLz8gVrYj","Wfg1pj76FwqHzu8MxPzc8ZdhS6BnTbAwhf","WZpycEKxsECAy84Yo49htDyYVqEkp1zGs3","WZFvR5bjjphpFMX8zdCUuz8FSYeasH1R8d","WZNHeftPrt6q9XCPMGDeJsvCxTfeK17Av6","Wde6n1xpamjwz6qQheHXYN5kabELF8GAu3","WP3nfCq9sV4TszCnDFBcB2FW5ZjZGeqEmv","WSJVxN12hFyneUrDza6uJ4dodMq2VKYLSE","WeeRsn1RxzTWaNg64PD9qwVuW1XKLuRhJ4","WjtMBcJyrMnziLZ513PqFyguS1PdX1QXqB","WYbki5PGkT9iscMUFQ4XeTxfC27269VyrJ","WVbyzZJBuvbD9UqDBKVM5f3ZPDFgFmyps3","Wbo1K3h1T618QMGfqSbehymw27ks5Cqkph"]}, +{"isUsed":false,"words":"syrup say again judge manage tiny strong marriage dune smoke design absorb genre key address coffee marine belt unable prize worry guilt cigar faith","addresses":["Wmc6DkmU25kUrHGoNZjDXF4XXoRYgAPFCE","WdmaCh83j6McXGByHLcsVLQY7ZnWCEQQEe","Whmnw4VL3NjZZqAE4SquZ3WY6yXoBZrwq9","WNwF71s5b5PkDqDqsiY2xxTN2iEVD7GxDR","WPEk9f1ZzhWWUHqyArJ5VuPBqhdSerK5QN","WbBzAANiS4TzFfxiLRjditQJ5j73gVeRKA","WQkAB213frdoMTUUZCKguT5nDuKpFiiJYN","WSCVwEUi9Dudk1kWaLWLo4HJbFrm77gUWo","WjMbk8af86abPNv1dnTAtnaGWdujWm1kq2","WknwzJMaGhqVZ1becR69rpYSV954b5T2SU","WSkuLUAqRtdTJxPDYQjew1YRtaArSoYbz3","WUGhoWUoU949kMnVsVxgCQLYVjDgWLMsnp","WmQn1e4vumnJtGNHcraAdznQLfsyiWkpCj","WT146vdNYVJ7KzVrybLrX1fUiFRbJQ95oT","WTNqJSCV6sHA2MdMdhGsp39RRPdmyTG8oC","WVXiw7ah16bhGF9X6F6PEQJCxunmQy3wf4","WkqvuJeDgyqZbX95sBWdd2DgreSA3vanUH","Wef8LocAxdBfe4P9ZrVnhSJj9dFhEoEKFN","WdnNsVHmYiGn5uURjkz8QWQaoQwaZS7HJJ","WQgoWmE1Fk7HmipZAv2stFho5ehHq5MfF5","WfHzLhChWuJUSdVzt5THZUQjuAzWi35Wv6","Wfmb8UFVRxNLX9YhmNYjCEte9TL8b5Nshf"]}, +{"isUsed":false,"words":"library lab roof panther ten repeat bunker palm type shop ordinary where diesel frequent bonus fade decline frame point alley carpet interest notice lunar","addresses":["WW1UcrX9MJPJRqhVSe3zU3WVStbjtSUZWo","Wee3mtJuUfG5Z93Z7SJLZNRR5KwsGeXxMb","WgUxmSpKpWv6K2E8iNeQ8PNe5PhbGbhrPn","WUvQbUme13c5PHGkAcBCDuZbmyeX6Rkosi","Wg5a9MQnohpFr4ATEbxvfaJEJ4zTuenRmm","WjgfUkrpiEBQ8rCdBvYah4kRwU1CkCRaBU","WW4QWja2VrWboHJ5sfvKnCmM3XRHtstk7d","WjR1AqStCmNzy2FN3YhXKHt24LeLSJ4SZG","WTQVKep5ho1xuFLmQVZpdkTMUG6MHN5MSg","WXfB3yx6MQYMNQ5637iqAJ8Gnh74LCbUWz","Wk83sqWsc2njmCPTtAng5AHT2xCZsGFJ42","Wbqzwtg41PQH75J35qMCR7o7Xg2JUJHeHm","WahvuxED3qqiJPaVfT9pJFNHt9YiDPT7Fv","WdZpwRrSy4pV8d5c1cixua9MwerKfXJ18h","WP6kDRQQdPktc4HGv35F6SM8TLnJS1KRzY","WYbWCrYKRQUVfZ6aug1oxfcCgStCUzYVzV","WVFB3GePJurpuRfHrCqZcYWArb27cKhdJP","WiDxnYQ87ugypX5vdfp8VtGuwwPhyrLst3","WirkR1guBQh9JvHfxZuKfbCQLpjfHMSm32","WjxzVHjdDfFHZi5FGbmBTQVyjE6HnX88mu","WcoP4X23eBGoBvHKvWi8GydTBYeroEGPLm","WgZdYjdiUB3YVgkGac57pjbv1PGrkHephG"]}, +{"isUsed":false,"words":"shadow develop remove beach truly record canal border bitter asset dawn ability rich naive pipe decline aerobic original forum hospital goose myth velvet diary","addresses":["WU5iaWuAYnqDWyPsSgm1C6PU818FyBTYMR","Whpp41cT7aqmCEetGVFqGaq8eYWmVDzYvo","WRogDav9jVpVMrAsukDch3AVs6NMGi4GPj","WTiFmd61gv1cM5jddb3hNLerCKNXeyF51M","WcZtQ9yoVg1CKkMjb77AApAJeumKDThfrZ","WSdL1x4QHn6wrHyqp2UsnBnkD8Gemi9sCM","WVcvMy5uTbtMtN5by4i2p5MEDQ2Nj7TfPJ","WSa7KeTcRjsSe2WT45sjXyAgF4FXa6MYSF","WTPkUsASfpSyF8Wmx14k7iUz4LXg6m39Bs","WYd1tRqygYB1j7QfBeQ4SYM9BEXfnGPEZX","WRmxUZrkiijsU26aStnenxjoAgrDDAmG9j","WkhhYXzp8AwefYatjpNe5rxsutPSQ2KMZj","Wc3LcfzD2sKboH2KSNK9kC9YJAqZryZgHe","WTZaqqY2FFXEfnHPGCdWmy1ws8XrFDhNrX","WPq5jzPcobWBTfu44PUKBjjnMWPwP3Tq1w","Wids84Qj3ArRU8kCLcfEMTPJwUa4h1nHK4","WTpFsmRQZi69jHDxHyVM7pEaPKLN3pYrvj","WVpZz3ar9cH3U3LPZYPVQJRMbpZtsct1jG","WkS4vpz25RWJvEJA2Abn4ibSxT9UbLaAfU","Wckmuwz8eHyyKfTH8kDp6VYkZHHy36RkFx","WSRvGfMsEhbG1tTnhaUi2pSPLtVxJP59XM","WYpbx4fvaFmnF8P9QT2SVMhv9TjnRtfnwG"]}, +{"isUsed":false,"words":"wagon spatial pumpkin fresh title divorce artwork route maximum accuse ahead baby dolphin force turtle little praise aware glare absurd payment various visa stomach","addresses":["Wi45HG5UaEeNsW3jQ3qt1wGpQPR47UPtQR","WSiq57CkS8HC8DKwnGmc1KtK4PhPTH6QWH","WgWTXQ1wDCp9dQr9bcgLjyqDDDsC1M3R72","WgDQqXmbP2eVDgr374Arg7taTgd5e8TytT","WZfyxwv34xYm4KLCSuRhr72dqreKghJmYD","Wj7tyUjL6LM3bD9jPbuaKEcCVWuknWBair","WhevN4m1Ziuw3vBU7dhsWQH15hokoGktrZ","WT4e8kSEwWLCMZH2tGZyoo7EFqqH9i2VCs","WTmGwiqxxvzxCawjvE1iStMA8A1KEv8BSW","WgAMqddzGMapYNknRdzdPEXAkf2N5rNpgP","WmP5Dgctz72d6WvjQLmvXTwaaK6BPdj1kZ","WXopqMj5sQh41Jkf4ZtheeUmdTsd4utjne","WPT9rDyotWxTLu6fn24jsCBrrRsbD3E8gh","WXZ3fZMyXfuDAKeScMYHvKuS8rzKHK241J","WhACBVmoAYFjSQX9YfWySefbzdNBsjGRXZ","Wb4MrBZ4tjwV8ZKJsXSy1P98DhiFNukX8j","WNqCk6SNHKFfoyvJunDiyQx65pCAWro74W","WPtwEd8tFiGp46GeZoULb8mtaHbXkbsfw9","WTD4X4UCpzr2h9qT8fa8AJoFUTstVgePY5","WiowHjRrWTxCBrs8TjPaj25tHdy7oehWTA","WcMJpXFj45CHUQ5MqWNMau4C8y8jccBBn7","WNpxSb62bsAurRCR15DYQDCoAPPvkkGuGu"]}, +{"isUsed":false,"words":"acid elegant fault midnight initial boil robust pulp gasp cradle island erosion defy tennis cart uncover flag index dinner stone leisure angry habit cry","addresses":["Wm8jnonmaQuVKtzuvmVZqHhFcLMZKnwsAH","WfMfJS69L7UdmHbwtrFvRUSmiboVTeK5Cn","WUZTZsVoMvud8HpMwxCCyEhK6uiDLFNanS","Weqpbi2VcYksb5pGjoNyBrB99E3wmpS1TV","WhTdVnh2hBAXbAJx8QR8KeCjEvExqJGvH5","Wmq8MWW6B7sUCWXXo7U25AAwbo5fxcBUhf","WcYn5xt69HyPDeMoSiFBKnqoGE8BS1XZ2W","WTrEykiQcGNEuyWEvsZtshPMhxQncKBEkn","Wf2ymqjcMLbZ9Wdo4MUCa1Zep88kUkY2Vr","WfUeNvAjYpoGHCZrTaXz7vEuphvoSTMgmW","WVowHCD1t7Y2BgGBnxewYG8teEAJNer49G","WiR3HBkKJM2C6JM3bKJVLcri9rvuPTPRvY","WaTDzxzK11tnPkH72v5S9RFMgsHhDSJ2FZ","WgCoTNyh52tucT5vanT5SavhHEupwjmo8F","WUruDZPcaprqdb2EQpiGRRSC2inGQ6SoPz","WRnzoRZVbesPmxsB2BckWq33kg4aun4AXB","WhisWiz1zYT7EsGhPTKuAswGUN1hy4xmEk","WeX3M5D6WXzu87Xu2pzVf2nSRacbS1mbZi","WeXBRA1rF5sZMP2jXt2uWPJECfMSkriUpK","WhBM9J9KfzDS5SkAMcDXYSRD2AzsY2tMWH","WjW8DmR2DrZd5P95EkLXYPgXCWwg77N2cE","WfDSyYrmoP8MF1Xwfbcu48bwF3UeNArppQ"]}, +{"isUsed":false,"words":"panda abstract vague wage risk below fame machine rubber act reason awesome police extra web negative screen close other zone swamp pencil trigger mask","addresses":["WZdmNEXoP9KQt3QWgSToR8LBKcyQ3qwH6W","WSJW6PbtG9RtGojAry44tRQUvDGVfVzBwm","WXiBaaJBdyoWPYFVyDhyvs7V4T2hc9EEjZ","WSfAWwcDNmn2mETYSuwrWREThTdi2Zz9MV","WRA1V7USXLrTa8WixNCtWXU5AR9GUTEHYc","WQk31ayw5M3Twz61LNsmxhVDmvpVN6zBEv","WZ9vV2QweA5vjpiSdwaKKa1xz3RFXc2KZW","WgpHB4Z6SBpf1P31TxdATjEjCfc6ckUE7y","WSPgCz289ti5hvBrLuqAPad3wrvq8pwAB8","WgwM62LcgwvgR9uLwnPbuaeXt4SPKp39Qt","WXpxapPzitLZ3zFYLUXsm2khNCZctjjtni","WQkbfEtiKBnPUgEb3ZUGJVjhKX71Ztnnu8","WkGHHonoBrzjDrT6Z9mBnbHGoTeL5vz1Da","WmuG4ssJYzvy2kNKFEayPujfABNeBiV8uQ","WfiJ7LaJJM13u6oE1du5h9yJ1uSENdnWeR","WVqoWedTdTDRVMpUn4c17A89UC9F7Ymtfx","WVBcuotanQtZP5z4Dcf8hFAK6n5s3upVhE","WW282rvJ9QBpfJMUk6YeeiZKuqPrfSrYsJ","WSyQmzSWBhg1xy5meiFKMoQorh1kxpYtXr","WdLS69e7zJPrqKyA3o2X2jMhkabofE9bBR","WPZRA3HCPzinQZXHymUqArwuAKpFVkCSQa","WcyHABDzQuUvrq47NtFRHCd2aAmQzmT2DX"]}, +{"isUsed":false,"words":"pill flash country type possible keen slow hen valid aisle right saddle alter ignore city drastic hunt apology bike party call end garlic feel","addresses":["WfNdTC3eyWfWGs9nP6wMZqAVeA746m4poJ","WgmNJp9PSH5znUfJNdzMD3AWY82FQh4WFn","WbzeEQUe5xuVndfTMj8mmAWt5WnH14Tte6","WTukQADmF15EqHw4RPaazG6SDgERZA1W8j","WTnLC8dKdxpefasU3e4DrA9HLsUiXCKEvz","WicGyKUZu4s8p4YxGnbjJEtrgab1hRfZA1","WitmHcoa5Z6oiKYwAnLATzf5pewRFLyuHm","WXH4F8pXjcJRgrhXAZqiHghD2yh6n32LTG","WeRSAk6EwSZCD88XyurYzeMBjrXK27RhsW","WWA1hbhTNMJQrZRn84qRThZQ3a79PUdPXn","WWFVtgzbC6TcJZMWqY6LDoxZKVrFNHyJkt","WQst1nWf9YNKfm5rnUGRqFjmXx1y6Qawhd","Wg8v4huGQa1wE3GqFzHbGCPQaGj8pumCKx","WejotH1Ca63ZLgnQWapZdXNgnoQzSm9zJ7","WVVkjTXgY2APQMYVgjNTURwUj21HphiAXJ","WiQptGHWPGvogEW4eRstJs3Fz6RkPvTfnq","WjKLszR8KzVYzHmDjEs2kw76gnPDg7mHdu","WQGNdesw2A8fLBazuvfoVbCDmby5LgCWwg","WjTj7q8mU6WLh5kTwoPzw6ztUTpLH9fruw","WgZeDPrT718u1JYCtKxQno3CNxxFfGzUMV","WWdqv3CnDb7AWKeXmAi67rvAQnMQyKvpgh","WiTtbS4sr9BRj8SoVnpmLUiu1jXe5N6ZvE"]}, +{"isUsed":false,"words":"scan nurse hospital oppose improve lamp shoot logic carry result fire polar vital major faculty okay dance ceiling view once prevent minimum anger antenna","addresses":["WjUS6wuHMVrw5PDS4cq5ANQtjSr5F7Da1K","Wf4qx8YQeFLKgBkFPGYvYjCyrNCZ3LAsnQ","WfZHYMvQvoG529qRsAftdQCQUviVqpLSc9","WjKFGtkCRGEe6EZBZgtDuhxx4gL3voUKwn","WkE98EpZzukxjbY88eWrsNc7rTCLGFtnfo","WQzYh8GsBQRbN8tJKxhcJG5WdmuARqmNBV","WcGoXbp4LWdb29ENeT7nVZsbfs8LvtDBT8","WUHxbHkjWVWaiMnAQxsTo6HAJrrf4zf39p","WmC5CwdMoPpP3KnnGNGnSJF9Wqj4Ai7KpP","WPp5zFBAg8rGcskMrcVxTC1tWdFFtMbZ5P","WfH5zQwrbF8f5tbsSx1s9aWi3SctotTSUc","WPXTCzVrgrBM8xCFAiT5fwUgmsVkEamnWu","WkkE5yNGeFnyygZUtgeHGB7qULtmJuJSDR","WcrsZghnVRaMzbLARYz4Dyjz5zFHgHqr5F","WmEU4NKDTK8jQbRMaiCbYAjbaaDGMC8ZXA","WhvVT2aGxrruyZYmMAXnn2TTonSy7SaCmG","WXno7TstQgKfKYG6oaD2F3erppnryYYqmc","WRd4yxBPExuu3ooVFnJvSJHAedySCLqrWg","WevhQBcBGgTZxJogitJFHtSqs6FdcgnVhi","WUUiTYzS8uxioPLNeb39zUhPfsUHTSYrSH","WgSNMBvCE2SZyXtbrGGRQDWG65akskKzSN","WZrSCcTJtSNnmMv7ZPJxBKXZcxC9D8zSnu"]}, +{"isUsed":false,"words":"artefact turtle weapon code seed organ cart crouch vault amateur ticket outdoor brick van base fatigue salute awake job absurd ginger unusual grass nerve","addresses":["WSMvRBstvezxCPVHaeEVNVmiNvaUKNLcFa","WjvFDGdMujacW2RrG9K8CXM4NzZSKLEiHu","WShwneBrq5LLd1xeUBzEDHtGpWxq2hNyrD","WNyByT6tXjaHMK7p8HH1TeBKhyqwDK3SXY","WQ8bbuH9cjmuW9t4fhN5FB2kg2RzRnVPyi","WTEuMLw2tTVDFm9xHAVP2HkZxD9psSVw4W","Wdywk5mua2BXcFq8yESLEz7C97bUDw2gtM","WjGNoSGGc23EXpVAaXmzFh5ixZLV8ShW95","WVQBP4o9sCy2eMEc9hkgRZXzzd1G9dUT5E","WiwqZ2hu7aUvLN5Y25Xzd64uCF2NkdRGeo","WjJMSGKjc8DE1xSHkb8QBM578wLM7R8L3S","WiMs5tQqwZB2oQ24v4s5jU47yaGiWdTfFY","WcszBVKJMxw6AJxBJW6WS1rfc27Ep5ZDJB","WTTrXvb5SpKUNc62vnqBviDDyrUrfVmkT5","WgAmerFQ9HxZ6QAkxvgSX7gG79csbF1Ggp","Wjg4ocjAhwiZUTXHuiF2BMVvjxW24vQu9S","WWFXL88N2nHJZcDGYNxCQMobmNht11vz1q","Wh5S6bcEHqK4KtcvcwrRAF5kodz563BwGi","WjWgtNU6Yy5mqzg42f2veaDV21ja6bTjjN","WQ7r63z64P65MYGm4bysLjPak9e3tUV9WF","WcqHE93eDYPK83Q6dCMqRmrrwQrhv3SSun","WcVAZ2jMg478mJTv8gFJ9XYKWuZNTtQrVw"]}, +{"isUsed":false,"words":"employ client guilt leave during broom lobster horn hundred parrot mammal toward amused mutual helmet grace ahead approve false away custom poverty garlic truly","addresses":["WjSwdTm6W3aNE7g46XjS2VwSYX7b3VhnCd","WasGnackDFsxMTpPS41ZSmbuBVMyRZhUwj","WfjpE9haWkN6FjoWzfY6wDabfFmHVZSq2C","Wekhp2axBZvcEUv5TSythKmhnG1LcZARjJ","WfNa8a18AkeFukqgvYq5wksF2uQrhctBrV","WSo9yBKb1cCQ2LSNwyrsRpoAQG5QrnmeRD","WWjNh6vup2Kgbv3M4GbWCW12sVBSBfVcmi","WhxRzjcFt4jdvaAiDZDtiXjM4853yZixnn","WUDkQyrNfTtmVdHHkWeuxeMzpp7zGQGxiu","WauE9QP1gNeQoVHepQDxy8VHVQw6ZtaEZW","WiHfDPACjXsq5Lw87AdosSrEkYMJTKADDy","WfTSGpzMsDurcmz2reZbaEbQPzhYsf3oej","WNttem1srCeDoBbfwiPnY41aSP6qaC5BeB","WdU5mQmPt8vWxeFWr5zMQJZx3GQJzHSH62","WRmLFbaVZBGrnNXNdJ6jbZkzaYCgeHfvNQ","WehtnRaSSQbA1zzH1qdUFT8rcxTUHdBsZi","Whmo8Xbm8ciQVZadKyVsQu6ooYhSmYNcFd","WhyQUfQr6PCjvwUJF4hhXhmTZKZt89Kcvx","WYV3XGrHsGjmJppofQay8XRF6pjcJSaiPd","WSrY7pGxijWfESXA4hvhPwQJ5ShrhQKJDe","WYUht55qqMwJpC1scdkhUmpqFky6veByuV","WcKED553bGEiNVceSRPCe322JcDfDBvxY1"]}, +{"isUsed":false,"words":"someone brick acoustic tide case dial version alarm syrup brief plug human glimpse off skate seminar stone crisp super squirrel credit fresh pair fly","addresses":["WiBHYttPxHFei4Pj68dLPkn7CtcFrVMmvA","WSUwdHH3cesLqkDz3cEgZX9ZKN1hu8EZc7","WXAi57Dy8vmRVVEMWaaxvmvXCqge2TX6Z3","WWHDYjkGKeMT6qumLdbbr3jEiQtz4wheD2","WaVur9SjFwqmhgZF7EAME2kY56y3XKtT3L","Wm9z7sL5bZdfGYxZ2uxDqEtKKDy2YaEKc3","WiwmMZYqQzu6GJMyxy9bMM9dzPHi9CnYTW","WQ1YaPT7EbvReddUXyEWJ1smSAgDiciExE","WkSggKzB1osxLCjqYcKUQSBRCaagqp1Peg","WQ3ZdUBCEemY6Lb7rvWR3gPHjsTHv19rfJ","WfJsWGPyZCnk8tLQUZjCMwPnax1qaxVEbf","WXVsZ6p7UxQ5pVJ3vhcMWCZ7kciUyi2ySK","WivuASCQ1EHMmBKxEGC9RuuQLjYHyK3aLT","Wf1FupD7cEEYSahrDtbktDEji6VufpNXZP","WeAyBJSkys7fatEmv9E8RUBYJuVdeuJTUK","WZMaVnnaV82SAMW5P27YbXEpzbwGYaiR6H","WgvhprXrXxDimsWyQeN6YXySd1Yg5Q5pxG","WijQzFZe4FA8on3eiXFvqP7qjKcWjYRrQd","WUpaBEaPGnUvuggvA3vzWFPs9tb97PNdCr","WaZo171eowXc7MCsw6yR87mNjoDsZ8MUvP","Wie6JLDUvsXAxTxUojjd4jmivVM5oeD9Yu","Whx19wm16BV4PfgFWCAZTvGvtGZd8F1NEw"]} +] \ No newline at end of file diff --git a/__tests__/integration/configuration/privnet.yml b/__tests__/integration/configuration/privnet.yml index 705d2dcd0..496c71887 100644 --- a/__tests__/integration/configuration/privnet.yml +++ b/__tests__/integration/configuration/privnet.yml @@ -31,6 +31,7 @@ CHECKPOINTS: [] ENABLE_NANO_CONTRACTS: enabled NC_ON_CHAIN_BLUEPRINT_RESTRICTED: false -AVG_TIME_BETWEEN_BLOCKS: 5 +AVG_TIME_BETWEEN_BLOCKS: 1 +FEE_PER_OUTPUT: 1 extends: mainnet.yml diff --git a/__tests__/integration/hathorwallet_facade.test.ts b/__tests__/integration/hathorwallet_facade.test.ts index 3156ddb8b..206511789 100644 --- a/__tests__/integration/hathorwallet_facade.test.ts +++ b/__tests__/integration/hathorwallet_facade.test.ts @@ -21,6 +21,7 @@ import { TOKEN_MELT_MASK, TOKEN_MINT_MASK, P2PKH_ACCT_PATH, + TOKEN_AUTHORITY_MASK, } from '../../src/constants'; import { TOKEN_DATA, WALLET_CONSTANTS } from './configuration/test-constants'; import dateFormatter from '../../src/utils/date'; @@ -31,10 +32,13 @@ import SendTransaction from '../../src/new/sendTransaction'; import { ConnectionState } from '../../src/wallet/types'; import transaction from '../../src/utils/transaction'; import Network from '../../src/models/network'; -import { WalletType } from '../../src/types'; +import { WalletType, TokenVersion } from '../../src/types'; import { parseScriptData } from '../../src/utils/scripts'; import { MemoryStore, Storage } from '../../src/storage'; import { TransactionTemplateBuilder } from '../../src/template/transaction'; +import FeeHeader from '../../src/headers/fee'; +import Header from '../../src/headers/base'; +import CreateTokenTransaction from '../../src/models/create_token_transaction'; const fakeTokenUid = '008a19f84f2ae284f19bf3d03386c878ddd15b8b0b604a3a3539aa9d714686e1'; const sampleNftData = @@ -578,6 +582,7 @@ describe('start', () => { id: tokenUid, name: 'Dedicated Wallet Token', symbol: 'DWT', + version: TokenVersion.DEPOSIT, }, balance: { unlocked: 100n, @@ -1375,6 +1380,21 @@ describe('graphvizNeighborsQuery', () => { }); }); +const validateFeeAmount = (headers: Header[], amount: bigint) => { + // validate fee amount + expect(headers).toHaveLength(1); + expect(headers[0]).toEqual( + expect.objectContaining({ + entries: expect.arrayContaining([ + expect.objectContaining({ + tokenIndex: 0, + amount, + }), + ]), + }) + ); +}; + describe('sendTransaction', () => { afterEach(async () => { await stopAllWallets(); @@ -1521,6 +1541,128 @@ describe('sendTransaction', () => { await hWallet.storage.getAddressInfo(await hWallet.getAddressAtIndex(12)) ).toHaveProperty('numTransactions', 1); }); + it('should send custom fee token transactions', async () => { + const hWallet = await generateWalletHelper(); + await GenesisWalletHelper.injectFunds(hWallet, await hWallet.getAddressAtIndex(0), 10n); + const { hash: tokenUid } = await createTokenHelper(hWallet, 'FeeBasedToken', 'FBT', 8582n, { + tokenVersion: TokenVersion.FEE, + }); + + const tx1 = await hWallet.sendTransaction(await hWallet.getAddressAtIndex(5), 8000n, { + token: tokenUid, + changeAddress: await hWallet.getAddressAtIndex(6), + }); + validateFeeAmount(tx1.headers, 2n); + await waitForTxReceived(hWallet, tx1.hash); + + // Validating balance stays the same for internal transactions + let fbtBalance = await hWallet.getBalance(tokenUid); + expect(fbtBalance[0].balance.unlocked).toEqual(8582n); + + expect(await hWallet.storage.getAddressInfo(await hWallet.getAddressAtIndex(5))).toHaveProperty( + 'numTransactions', + 1 + ); + expect(await hWallet.storage.getAddressInfo(await hWallet.getAddressAtIndex(6))).toHaveProperty( + 'numTransactions', + 1 + ); + + // Transaction outside the wallet + const { hWallet: gWallet } = await GenesisWalletHelper.getSingleton(); + await waitUntilNextTimestamp(hWallet, tx1.hash); + const { hash: tx2Hash, headers: tx2Headers } = await hWallet.sendTransaction( + await gWallet.getAddressAtIndex(0), + 82n, + { + token: tokenUid, + changeAddress: await hWallet.getAddressAtIndex(12), + } + ); + validateFeeAmount(tx2Headers, 2n); + await waitForTxReceived(hWallet, tx2Hash); + await waitForTxReceived(gWallet, tx2Hash); + + // Balance was reduced + fbtBalance = await hWallet.getBalance(tokenUid); + expect(fbtBalance[0].balance.unlocked).toEqual(8500n); + + const htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0].balance.unlocked).toEqual(5n); + + expect(await hWallet.storage.getAddressInfo(await hWallet.getAddressAtIndex(5))).toHaveProperty( + 'numTransactions', + 1 + ); + expect(await hWallet.storage.getAddressInfo(await hWallet.getAddressAtIndex(6))).toHaveProperty( + 'numTransactions', + 2 + ); + expect( + await hWallet.storage.getAddressInfo(await hWallet.getAddressAtIndex(12)) + ).toHaveProperty('numTransactions', 1); + }); + + it('should send fee token with manually provided HTR input (no HTR output)', async () => { + const hWallet = await generateWalletHelper(); + await GenesisWalletHelper.injectFunds(hWallet, await hWallet.getAddressAtIndex(0), 10n); + const { hash: tokenUid } = await createTokenHelper( + hWallet, + 'FeeTokenManualInput', + 'FTMI', + 100n, + { + tokenVersion: TokenVersion.FEE, + } + ); + + // Get UTXOs for both HTR and the fee token + const { utxos: utxosHtr } = await hWallet.getUtxos({ token: NATIVE_TOKEN_UID }); + const { utxos: utxosToken } = await hWallet.getUtxos({ token: tokenUid }); + + // Get the first UTXO of each token + const htrUtxo = utxosHtr[0]; + const tokenUtxo = utxosToken[0]; + + // Send transaction with manually provided inputs (HTR + token) and only token output + // This tests the scenario where user provides HTR input to pay for fee + // but has no HTR output (only token output) + const tx = await hWallet.sendManyOutputsTransaction( + [ + { + address: await hWallet.getAddressAtIndex(5), + value: 50n, + token: tokenUid, + }, + ], + { + inputs: [ + { txId: htrUtxo.tx_id, index: htrUtxo.index }, + { txId: tokenUtxo.tx_id, index: tokenUtxo.index }, + ], + } + ); + + validateFeeAmount(tx.headers, 2n); + await waitForTxReceived(hWallet, tx.hash); + + // Validate the transaction was created correctly + const decodedTx = await hWallet.getTx(tx.hash); + + // Should have 2 inputs (HTR + token) + expect(decodedTx.inputs).toHaveLength(2); + expect(decodedTx.inputs).toContainEqual( + expect.objectContaining({ tx_id: htrUtxo.tx_id, index: htrUtxo.index }) + ); + expect(decodedTx.inputs).toContainEqual( + expect.objectContaining({ tx_id: tokenUtxo.tx_id, index: tokenUtxo.index }) + ); + + // Should have outputs: token output (50) + token change (50) + HTR change + expect(decodedTx.outputs).toContainEqual( + expect.objectContaining({ value: 50n, token: tokenUid }) + ); + }); it('should send a multisig transaction', async () => { // Initialize 3 wallets from the same multisig and inject funds in them to test @@ -1906,9 +2048,39 @@ describe('createNewToken', () => { // Validating wallet balance is updated with this new token await waitForTxReceived(hWallet, tokenUid); const tknBalance = await hWallet.getBalance(tokenUid); + expect(tknBalance[0].token.version).toBe(TokenVersion.DEPOSIT); expect(tknBalance[0].balance.unlocked).toBe(100n); }); + it('should create a new token fee token', async () => { + // Creating the wallet with the funds + const hWallet = await generateWalletHelper(); + const addr0 = await hWallet.getAddressAtIndex(0); + await GenesisWalletHelper.injectFunds(hWallet, addr0, 10n); + + // Creating the new token + const newTokenResponse = await hWallet.createNewToken('TokenName', 'TKN', 8582n, { + tokenVersion: TokenVersion.FEE, + }); + + // Validating the creation tx + expect(newTokenResponse).toMatchObject({ + hash: expect.any(String), + name: 'TokenName', + symbol: 'TKN', + version: 2, + tokenVersion: TokenVersion.FEE, + headers: [new FeeHeader([{ tokenIndex: 0, amount: 1n }])], + }); + const tokenUid = newTokenResponse.hash; + + // Validating wallet balance is updated with this new token + await waitForTxReceived(hWallet, tokenUid); + const tknBalance = await hWallet.getBalance(tokenUid); + expect(tknBalance[0].token.version).toBe(TokenVersion.FEE); + expect(tknBalance[0].balance.unlocked).toBe(8582n); + }); + it('should create a new token on the correct addresses', async () => { // Creating the wallet with the funds const hWallet = await generateWalletHelper(); @@ -1918,20 +2090,30 @@ describe('createNewToken', () => { // Creating the new token const destinationAddress = await hWallet.getAddressAtIndex(4); const changeAddress = await hWallet.getAddressAtIndex(8); - const { hash: tokenUid } = await hWallet.createNewToken('NewToken Name', 'NTKN', 100n, { + const { hash: dbtUid } = await hWallet.createNewToken('NewToken Name', 'NTKN', 100n, { address: destinationAddress, changeAddress, }); - await waitForTxReceived(hWallet, tokenUid); + await waitForTxReceived(hWallet, dbtUid); + const { hash: fbtUid } = await hWallet.createNewToken('FeeBasedToken', 'FBT', 8582n, { + address: destinationAddress, + changeAddress, + tokenVersion: TokenVersion.FEE, + }); + await waitForTxReceived(hWallet, fbtUid); // Validating the tokens are on the correct addresses - const { utxos: utxosTokens } = await hWallet.getUtxos({ token: tokenUid }); - expect(utxosTokens).toContainEqual( + const { utxos: utxosDbt } = await hWallet.getUtxos({ token: dbtUid }); + const { utxos: utxosFbt } = await hWallet.getUtxos({ token: fbtUid }); + expect(utxosDbt).toContainEqual( expect.objectContaining({ address: destinationAddress, amount: 100n }) ); + expect(utxosFbt).toContainEqual( + expect.objectContaining({ address: destinationAddress, amount: 8582n }) + ); const { utxos: utxosHtr } = await hWallet.getUtxos(); expect(utxosHtr).toContainEqual( - expect.objectContaining({ address: changeAddress, amount: 9n }) + expect.objectContaining({ address: changeAddress, amount: 8n }) ); }); @@ -1939,21 +2121,28 @@ describe('createNewToken', () => { // Creating the wallet with the funds const hWallet = await generateWalletHelper(); const addr0 = await hWallet.getAddressAtIndex(0); - await GenesisWalletHelper.injectFunds(hWallet, addr0, 1n); + await GenesisWalletHelper.injectFunds(hWallet, addr0, 2n); // Creating the new token - const newTokenResponse = await hWallet.createNewToken('Immutable Token', 'ITKN', 100n, { + const dbtResponse = await hWallet.createNewToken('Immutable Token', 'ITKN', 100n, { createMint: false, createMelt: false, }); + expect(dbtResponse).toHaveProperty('hash'); + await waitForTxReceived(hWallet, dbtResponse.hash); + let htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', 1n); - // Validating the creation tx - expect(newTokenResponse).toHaveProperty('hash'); - - // Checking for authority outputs on the transaction - const authorityOutputs = newTokenResponse.outputs.filter(o => transaction.isAuthorityOutput(o)); - expect(authorityOutputs).toHaveLength(0); - await waitForTxReceived(hWallet, newTokenResponse.hash); + const fbtResponse = await hWallet.createNewToken('FeeBasedToken', 'FBT', 8582n, { + createMint: false, + createMelt: false, + tokenVersion: TokenVersion.FEE, + }); + expect(fbtResponse).toHaveProperty('hash'); + validateFeeAmount(fbtResponse.headers, 1n); + await waitForTxReceived(hWallet, fbtResponse.hash); + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', 0n); }); it('Create token using mint/melt address', async () => { @@ -1962,39 +2151,57 @@ describe('createNewToken', () => { const addr0 = await hWallet.getAddressAtIndex(0); const addr10 = await hWallet.getAddressAtIndex(10); const addr11 = await hWallet.getAddressAtIndex(11); - await GenesisWalletHelper.injectFunds(hWallet, addr0, 1n); + await GenesisWalletHelper.injectFunds(hWallet, addr0, 2n); // Creating the new token - const newTokenResponse = await hWallet.createNewToken('New Token', 'NTKN', 100n, { + const dbtResponse = await hWallet.createNewToken('New Token', 'NTKN', 100n, { createMint: true, mintAuthorityAddress: addr10, createMelt: true, meltAuthorityAddress: addr11, }); - // Validating the creation tx - expect(newTokenResponse).toHaveProperty('hash'); - await waitForTxReceived(hWallet, newTokenResponse.hash); + expect(dbtResponse).toHaveProperty('hash'); + await waitForTxReceived(hWallet, dbtResponse.hash); - // Validating a new mint authority was created by default - const authorityOutputs = newTokenResponse.outputs.filter(o => - transaction.isAuthorityOutput({ token_data: o.tokenData }) - ); - expect(authorityOutputs).toHaveLength(2); - const mintOutput = authorityOutputs.filter(o => o.value === TOKEN_MINT_MASK); - const mintP2pkh = mintOutput[0].parseScript(hWallet.getNetworkObject()); - // Validate that the mint output was sent to the correct address - expect(mintP2pkh.address.base58).toEqual(addr10); + // Creating the new token + const fbtResponse = await hWallet.createNewToken('New Token', 'NTKN', 8582n, { + createMint: true, + mintAuthorityAddress: addr10, + createMelt: true, + meltAuthorityAddress: addr11, + tokenVersion: TokenVersion.FEE, + }); - const meltOutput = authorityOutputs.filter(o => o.value === TOKEN_MELT_MASK); - const meltP2pkh = meltOutput[0].parseScript(hWallet.getNetworkObject()); - // Validate that the melt output was sent to the correct address - expect(meltP2pkh.address.base58).toEqual(addr11); + expect(fbtResponse).toHaveProperty('hash'); + await waitForTxReceived(hWallet, fbtResponse.hash); - // Validating custom token balance - const tokenBalance = await hWallet.getBalance(newTokenResponse.hash); - const expectedAmount = 100n; - expect(tokenBalance[0]).toHaveProperty('balance.unlocked', expectedAmount); + const validateAuthorityOutputs = async ( + response: CreateTokenTransaction, + expectedAmount: bigint + ) => { + // Validating a new mint authority was created by default + const authorityOutputs = response.outputs.filter(o => + transaction.isAuthorityOutput({ token_data: o.tokenData }) + ); + expect(authorityOutputs).toHaveLength(2); + const mintOutput = authorityOutputs.filter(o => o.value === TOKEN_MINT_MASK); + const mintP2pkh = mintOutput[0].parseScript(hWallet.getNetworkObject()); + // Validate that the mint output was sent to the correct address + expect(mintP2pkh.address.base58).toEqual(addr10); + + const meltOutput = authorityOutputs.filter(o => o.value === TOKEN_MELT_MASK); + const meltP2pkh = meltOutput[0].parseScript(hWallet.getNetworkObject()); + // Validate that the melt output was sent to the correct address + expect(meltP2pkh.address.base58).toEqual(addr11); + + // Validating custom token balance + const tokenBalance = await hWallet.getBalance(response.hash); + expect(tokenBalance[0]).toHaveProperty('balance.unlocked', expectedAmount); + }; + + validateAuthorityOutputs(dbtResponse, 100n); + validateAuthorityOutputs(fbtResponse, 8582n); }); it('Create token using external mint/melt address', async () => { @@ -2067,13 +2274,27 @@ describe('mintTokens', () => { it('should mint new tokens', async () => { // Setting up the custom token const hWallet = await generateWalletHelper(); - await GenesisWalletHelper.injectFunds(hWallet, await hWallet.getAddressAtIndex(0), 10n); + await GenesisWalletHelper.injectFunds(hWallet, await hWallet.getAddressAtIndex(0), 2n); const { hash: tokenUid } = await createTokenHelper(hWallet, 'Token to Mint', 'TMINT', 100n); + const options = { tokenVersion: TokenVersion.FEE }; + const { hash: fbtUid } = await createTokenHelper( + hWallet, + 'FeeBasedToken', + 'FBT', + 8582n, + options + ); + await waitForTxReceived(hWallet, fbtUid); // Should not mint more tokens than the HTR funds allow await expect(hWallet.mintTokens(tokenUid, 9000n)).rejects.toThrow( - /^Not enough HTR tokens for deposit: 90 required, \d+ available$/ + /^Not enough HTR tokens for deposit or fee: 90 required, \d+ available$/ ); + await expect(hWallet.mintTokens(fbtUid, 9000n)).rejects.toThrow( + /^Not enough HTR tokens for deposit or fee: 1 required, \d+ available$/ + ); + + await GenesisWalletHelper.injectFunds(hWallet, await hWallet.getAddressAtIndex(0), 9n); // Minting more of the tokens const mintAmount = BigInt(getRandomInt(100, 50)); @@ -2182,9 +2403,15 @@ describe('mintTokens', () => { const expectedAmount5 = expectedAmount4 + 100n; expect(tokenBalance5[0]).toHaveProperty('balance.unlocked', expectedAmount5); - const dataOutput5 = mintResponse5.outputs[mintResponse5.outputs.length - 1]; - expect(dataOutput5).toHaveProperty('value', 1n); - expect(dataOutput5).toHaveProperty('script', Buffer.from([6, 102, 111, 111, 98, 97, 114, 172])); + const dataOutput5 = mintResponse5.outputs.filter( + o => o.getType(hWallet.getNetworkObject()) === 'data' + ); + expect(dataOutput5).toHaveLength(1); + expect(dataOutput5[0]).toHaveProperty('value', 1n); + expect(dataOutput5[0]).toHaveProperty( + 'script', + Buffer.from([6, 102, 111, 111, 98, 97, 114, 172]) + ); const mintResponse6 = await hWallet.mintTokens(tokenUid, 100n, { unshiftData: true, @@ -2220,9 +2447,12 @@ describe('mintTokens', () => { // Setting up scenario const hWallet = await generateWalletHelper(); - await GenesisWalletHelper.injectFunds(hWallet, await hWallet.getAddressAtIndex(0), 10n); + await GenesisWalletHelper.injectFunds(hWallet, await hWallet.getAddressAtIndex(0), 13n); const { hash: tokenUid } = await createTokenHelper(hWallet, 'Token to Mint', 'TMINT', 100n); - let expectedHtrFunds = 9n; + const { hash: fbtUid } = await createTokenHelper(hWallet, 'FeeBasedToken', 'FBT', 8582n, { + tokenVersion: TokenVersion.FEE, + }); + let expectedHtrFunds = 11n; // Minting less than 1.00 tokens consumes 0.01 HTR let mintResponse; @@ -2258,6 +2488,63 @@ describe('mintTokens', () => { expectedHtrFunds -= 3n; await waitForTxReceived(hWallet, mintResponse.hash); expect(await getHtrBalance(hWallet)).toBe(expectedHtrFunds); + + // fee token minting + // minting less than 1.00 tokens consumes 0.01 HTR based in the outputs length + mintResponse = await hWallet.mintTokens(fbtUid, 1n); + expectedHtrFunds -= 1n; + expect(mintResponse.tokens.length).toBe(1); + expect(mintResponse.outputs).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + tokenData: 0, + value: expectedHtrFunds, + }), + expect.objectContaining({ + tokenData: 1, + value: 1n, + }), + expect.objectContaining({ + tokenData: TOKEN_AUTHORITY_MASK + 1, + value: TOKEN_MINT_MASK, + }), + ]) + ); + expect(mintResponse.headers).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + entries: expect.arrayContaining([ + expect.objectContaining({ + tokenIndex: 0, + amount: 1n, + }), + ]), + }), + ]) + ); + await waitForTxReceived(hWallet, mintResponse.hash); + expect(await getHtrBalance(hWallet)).toBe(expectedHtrFunds); + + // minting any amount of tokens should consume 0.01 HTR + const randomMintAmount = BigInt(Math.floor(Math.random() * (1_000_000_000 - 2 + 1)) + 2); + mintResponse = await hWallet.mintTokens(fbtUid, randomMintAmount); + expect(mintResponse.tokens.length).toBe(1); + expect(mintResponse.outputs).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + tokenData: 1, + value: randomMintAmount, + }), + expect.objectContaining({ + tokenData: TOKEN_AUTHORITY_MASK + 1, + value: TOKEN_MINT_MASK, + }), + ]) + ); + validateFeeAmount(mintResponse.headers, 1n); + expectedHtrFunds -= 1n; + await waitForTxReceived(hWallet, mintResponse.hash); + expect(await getHtrBalance(hWallet)).toBe(expectedHtrFunds); }); }); @@ -2388,6 +2675,181 @@ describe('meltTokens', () => { expect(dataOutput5).toHaveProperty('script', Buffer.from([6, 102, 111, 111, 98, 97, 114, 172])); }); + it('should melt fee based tokens', async () => { + const hWallet = await generateWalletHelper(); + let expectedHtrAmount = 15n; + await GenesisWalletHelper.injectFunds( + hWallet, + await hWallet.getAddressAtIndex(0), + expectedHtrAmount + ); + + // Creating the token + const { hash: fbtUid } = await createTokenHelper(hWallet, 'FeeBasedToken', 'FBT', 8582n, { + tokenVersion: TokenVersion.FEE, + }); + expectedHtrAmount -= 1n; // 14 + + let htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + // Should not melt more than there is available + await expect(hWallet.meltTokens(fbtUid, 99999n)).rejects.toThrow( + 'Not enough tokens to melt: 99999 requested, 8582 available' + ); + + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + // Melting some tokens + const meltAmount = BigInt(getRandomInt(99, 10)); + const { hash, headers } = await hWallet.meltTokens(fbtUid, meltAmount); + await waitForTxReceived(hWallet, hash); + validateFeeAmount(headers, 1n); + expectedHtrAmount -= 1n; // 13 + + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + // Validating custom token balance + const tokenBalance = await hWallet.getBalance(fbtUid); + const expectedAmount = 8582n - meltAmount; + expect(tokenBalance[0]).toHaveProperty('balance.unlocked', expectedAmount); + + // Melt tokens with defined melt authority address + const address0 = await hWallet.getAddressAtIndex(0); + const meltResponse = await hWallet.meltTokens(fbtUid, 1000n, { + meltAuthorityAddress: address0, + }); + validateFeeAmount(meltResponse.headers, 1n); + await waitForTxReceived(hWallet, meltResponse.hash); + expectedHtrAmount -= 1n; // 12 + + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + // Validating a new melt authority was created by default + const authorityOutputs = meltResponse.outputs.filter(o => + transaction.isAuthorityOutput({ token_data: o.tokenData }) + ); + expect(authorityOutputs).toHaveLength(1); + const authorityOutput = authorityOutputs[0]; + expect(authorityOutput.value).toEqual(TOKEN_MELT_MASK); + const p2pkh = authorityOutput.parseScript(hWallet.getNetworkObject()); + // Validate that the authority output was sent to the correct address + expect(p2pkh.address.base58).toEqual(address0); + + // Validating custom token balance + const tokenBalance2 = await hWallet.getBalance(fbtUid); + const expectedAmount2 = expectedAmount - 1000n; + expect(tokenBalance2[0]).toHaveProperty('balance.unlocked', expectedAmount2); + + // Melt tokens with external address should return error + const hWallet2 = await generateWalletHelper(); + const externalAddress = await hWallet2.getAddressAtIndex(0); + + await expect( + hWallet.meltTokens(fbtUid, 100n, { meltAuthorityAddress: externalAddress }) + ).rejects.toThrow('must belong to your wallet'); + + // Melt tokens with external address but allowing it + const meltResponse3 = await hWallet.meltTokens(fbtUid, 100n, { + meltAuthorityAddress: externalAddress, + allowExternalMeltAuthorityAddress: true, + }); + validateFeeAmount(meltResponse3.headers, 1n); + await waitForTxReceived(hWallet, meltResponse3.hash); + await waitForTxReceived(hWallet2, meltResponse3.hash); + expectedHtrAmount -= 1n; // 11 + + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + // Validating a new melt authority was created by default + const authorityOutputs3 = meltResponse3.outputs.filter(o => + transaction.isAuthorityOutput({ token_data: o.tokenData }) + ); + expect(authorityOutputs3).toHaveLength(1); + const authorityOutput3 = authorityOutputs3[0]; + expect(authorityOutput3.value).toEqual(TOKEN_MELT_MASK); + const p3pkh = authorityOutput3.parseScript(hWallet.getNetworkObject()); + // Validate that the authority output was sent to the correct address + expect(p3pkh.address.base58).toEqual(externalAddress); + + // Validating custom token balance + const tokenBalance3 = await hWallet.getBalance(fbtUid); + const expectedAmount3 = expectedAmount2 - 100n; + expect(tokenBalance3[0]).toHaveProperty('balance.unlocked', expectedAmount3); + + // Delegate melt back to wallet 1 + const delegateResponse = await hWallet2.delegateAuthority(fbtUid, 'melt', address0); + expect(delegateResponse.hash).toBeDefined(); + await waitForTxReceived(hWallet, delegateResponse.hash); + await waitForTxReceived(hWallet2, delegateResponse.hash); + + const meltResponse4 = await hWallet.meltTokens(fbtUid, 100n, { data: ['foobar'] }); + validateFeeAmount(meltResponse4.headers, 1n); + expect(meltResponse4.hash).toBeDefined(); + await waitForTxReceived(hWallet, meltResponse4.hash); + expectedHtrAmount -= 2n; // 9 fee + 1 htr from data output + + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + // Validating there is a correct reference to the custom token + expect(meltResponse4).toHaveProperty('tokens.length', 1); + expect(meltResponse4.tokens[0]).toEqual(fbtUid); + + // Validating custom token balance + const tokenBalance4 = await hWallet.getBalance(fbtUid); + const expectedAmount4 = expectedAmount3 - 100n; + expect(tokenBalance4[0]).toHaveProperty('balance.unlocked', expectedAmount4); + + const dataOutput4 = meltResponse4.outputs[meltResponse4.outputs.length - 1]; + expect(dataOutput4).toHaveProperty('value', 1n); + expect(dataOutput4).toHaveProperty('script', Buffer.from([6, 102, 111, 111, 98, 97, 114, 172])); + + const meltResponse5 = await hWallet.meltTokens(fbtUid, 100n, { + unshiftData: true, + data: ['foobar'], + }); + validateFeeAmount(meltResponse.headers, 1n); + expect(meltResponse5.hash).toBeDefined(); + await waitForTxReceived(hWallet, meltResponse5.hash); + expectedHtrAmount -= 2n; // 7 fee + 1 htr from data output + + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + // Validating there is a correct reference to the custom token + expect(meltResponse5).toHaveProperty('tokens.length', 1); + expect(meltResponse5.tokens[0]).toEqual(fbtUid); + + // Validating custom token balance + const tokenBalance5 = await hWallet.getBalance(fbtUid); + const expectedAmount5 = expectedAmount4 - 100n; + expect(tokenBalance5[0]).toHaveProperty('balance.unlocked', expectedAmount5); + + const dataOutput5 = meltResponse5.outputs[0]; + expect(dataOutput5).toHaveProperty('value', 1n); + expect(dataOutput5).toHaveProperty('script', Buffer.from([6, 102, 111, 111, 98, 97, 114, 172])); + + // melting without any output should charge 1 fee + const meltResponse6 = await hWallet.meltTokens(fbtUid, expectedAmount5); + validateFeeAmount(meltResponse6.headers, 1n); + expect(meltResponse6.hash).toBeDefined(); + expect(meltResponse6.outputs).toHaveLength(2); + expect(meltResponse6.outputs.filter(o => o.tokenData === 1).length).toBe(0); + await waitForTxReceived(hWallet, meltResponse6.hash); + expectedHtrAmount -= 1n; // 6 fee + + htrBalance = await hWallet.getBalance(NATIVE_TOKEN_UID); + expect(htrBalance[0]).toHaveProperty('balance.unlocked', expectedHtrAmount); + + const tokenBalance6 = await hWallet.getBalance(fbtUid); + expect(tokenBalance6[0]).toHaveProperty('balance.unlocked', 0n); + }); + it('should recover correct amount of HTR on melting', async () => { /** * @@ -3037,7 +3499,12 @@ describe('getToken methods', () => { expect(details).toStrictEqual({ totalSupply: 100n, totalTransactions: 1, - tokenInfo: { id: tokenUid, name: 'Details Token', symbol: 'DTOK' }, + tokenInfo: { + id: tokenUid, + name: 'Details Token', + symbol: 'DTOK', + version: TokenVersion.DEPOSIT, + }, authorities: { mint: true, melt: true }, }); diff --git a/__tests__/models/transaction.test.ts b/__tests__/models/transaction.test.ts index 3a47ab55f..7ab1fa89a 100644 --- a/__tests__/models/transaction.test.ts +++ b/__tests__/models/transaction.test.ts @@ -16,10 +16,19 @@ import Network from '../../src/models/network'; import { hexToBuffer, bufferToHex } from '../../src/utils/buffer'; import helpers from '../../src/utils/helpers'; import { DEFAULT_TX_VERSION, MAX_OUTPUTS, DEFAULT_SIGNAL_BITS } from '../../src/constants'; -import { MaximumNumberInputsError, MaximumNumberOutputsError, ParseError } from '../../src/errors'; +import { + CreateTokenTxInvalid, + MaximumNumberInputsError, + MaximumNumberOutputsError, + ParseError, +} from '../../src/errors'; import { nftCreationTx } from '../__fixtures__/sample_txs'; +import { TokenVersion } from '../../src/types'; -const compareTxs = (tx, tx2) => { +const compareTxs = ( + tx: Transaction | CreateTokenTransaction, + tx2: Transaction | CreateTokenTransaction +) => { expect(tx2.version).toBe(tx.version); expect(tx2.tokens.length).toBe(tx.tokens.length); expect(tx2.inputs.length).toBe(tx.inputs.length); @@ -127,10 +136,12 @@ test('New tx', () => { }).toThrow(ParseError); }); -test('Token tx', () => { +test('Deposit token tx', () => { const network = new Network('testnet'); - const tx = new CreateTokenTransaction('Test', 'TST', [], []); - const info = []; + const tx = new CreateTokenTransaction('Test', 'TST', [], [], { + tokenVersion: TokenVersion.DEPOSIT, + }); + const info: Buffer[] = []; tx.serializeTokenInfo(info); expect(info.length).toBe(5); expect(info[2].toString('hex')).toBe('54657374'); @@ -157,7 +168,8 @@ test('Token tx', () => { ]; tx.hash = '723ca83484495bcbb4cf849a835800a28cfac5440a8f517fffb095c52c461858'; - const tx2 = helpers.createTxFromHex(tx.toHex(), network); + const tx2 = helpers.createTxFromHex(tx.toHex(), network) as CreateTokenTransaction; + expect(tx2).toBeInstanceOf(CreateTokenTransaction); compareTxs(tx, tx2); expect(tx2.name).toBe('Test'); @@ -166,6 +178,93 @@ test('Token tx', () => { expect(tx2.symbol).toBe(tx.symbol); }); +test('Fee token tx', () => { + // Arrange + const network = new Network('testnet'); + const tx = new CreateTokenTransaction('Test', 'TST', [], [], { + tokenVersion: TokenVersion.FEE, + }); + const info: Buffer[] = []; + tx.serializeTokenInfo(info); + expect(info.length).toBe(5); + expect(info[2].toString('hex')).toBe('54657374'); + expect(info[4].toString('hex')).toBe('545354'); + + const address1 = new Address('WR1i8USJWQuaU423fwuFQbezfevmT4vFWX'); + const p2pkh1 = new P2PKH(address1); + const p2pkhScript1 = p2pkh1.createScript(); + const output1 = new Output(1000n, p2pkhScript1); + output1.parseScript(network); + const inputDataHex = + '4630440220317cd233801c1986c2de900bf8d344c6335d3c385e69d19d65e1fae7a0afd0af02207acddb824debf855798d79c45701cbe3a19aea00baad94bff5290c6f0b0acf8e210346cddff43dffab8e13398633ab7a7caf0d634551e89ae6fd563e282f6744b983'; + const input1 = new Input('00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295e', 0, { + data: hexToBuffer(inputDataHex), + }); + tx.inputs = [input1]; + tx.outputs = [output1]; + tx.timestamp = 1550249810; + tx.weight = tx.calculateWeight(); + tx.nonce = 12345; + tx.parents = [ + '00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295e', + '00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295c', + ]; + tx.hash = 'ef164429258e1b5ba59f72888926d577035bf53a6761e8839dbc99b85053e735'; + + // Act + const tx2 = helpers.createTxFromHex(tx.toHex(), network) as CreateTokenTransaction; + + // Assert + expect(tx2).toBeInstanceOf(CreateTokenTransaction); + compareTxs(tx, tx2); + expect(tx2.name).toBe('Test'); + expect(tx2.symbol).toBe('TST'); + expect(tx2.name).toBe(tx.name); + expect(tx2.symbol).toBe(tx.symbol); + expect(tx2.tokenVersion).toBe(TokenVersion.FEE); +}); + +test('Invalid token info version tx', () => { + // Arrange + const invalidVersion = 99 as TokenVersion; + const network = new Network('testnet'); + const tx = new CreateTokenTransaction('Test', 'TST', [], [], { + tokenVersion: invalidVersion, + }); + const info: Buffer[] = []; + tx.serializeTokenInfo(info); + expect(info.length).toBe(5); + expect(info[2].toString('hex')).toBe('54657374'); + expect(info[4].toString('hex')).toBe('545354'); + + const address1 = new Address('WR1i8USJWQuaU423fwuFQbezfevmT4vFWX'); + const p2pkh1 = new P2PKH(address1); + const p2pkhScript1 = p2pkh1.createScript(); + const output1 = new Output(1000n, p2pkhScript1); + output1.parseScript(network); + const inputDataHex = + '4630440220317cd233801c1986c2de900bf8d344c6335d3c385e69d19d65e1fae7a0afd0af02207acddb824debf855798d79c45701cbe3a19aea00baad94bff5290c6f0b0acf8e210346cddff43dffab8e13398633ab7a7caf0d634551e89ae6fd563e282f6744b983'; + const input1 = new Input('00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295e', 0, { + data: hexToBuffer(inputDataHex), + }); + tx.inputs = [input1]; + tx.outputs = [output1]; + tx.timestamp = 1550249810; + tx.weight = tx.calculateWeight(); + tx.nonce = 12345; + tx.parents = [ + '00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295e', + '00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295c', + ]; + tx.hash = '723ca83484495bcbb4cf849a835800a28cfac5440a8f517fffb095c52c461858'; + + // Act + const act = () => () => helpers.createTxFromHex(tx.toHex(), network); + + // Assert + expect(act()).toThrow(CreateTokenTxInvalid); +}); + test('Tx validation', () => { const tx = new Transaction([], []); tx.validate(); @@ -174,7 +273,7 @@ test('Tx validation', () => { const p2pkh1 = new P2PKH(address1); const p2pkhScript1 = p2pkh1.createScript(); const output1 = new Output(1000n, p2pkhScript1); - const outputs = []; + const outputs: Output[] = []; for (let i = 0; i < 255; i++) { outputs.push(output1); } @@ -192,7 +291,7 @@ test('Tx validation', () => { tx.outputs = []; - const inputs = []; + const inputs: Input[] = []; const input1 = new Input('abc', 0); for (let i = 0; i < 255; i++) { inputs.push(input1); @@ -213,13 +312,13 @@ test('Transaction type', () => { const address1 = new Address('1PtH3rBmiYDiUuomQyoxMREicrxjg3LA5q'); const p2pkh1 = new P2PKH(address1); const p2pkhScript1 = p2pkh1.createScript(); - const outputs1 = [new Output(100, p2pkhScript1), new Output(300, p2pkhScript1)]; + const outputs1 = [new Output(100n, p2pkhScript1), new Output(300n, p2pkhScript1)]; const tx1 = new Transaction([], outputs1, { version: 1, hash: '00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295e', }); - const outputs2 = [new Output(100, p2pkhScript1), new Output(300, p2pkhScript1)]; + const outputs2 = [new Output(100n, p2pkhScript1), new Output(300n, p2pkhScript1)]; const inputs2 = [ new Input('00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295e', 0), ]; @@ -228,7 +327,7 @@ test('Transaction type', () => { hash: '00034a15973117852c45520af9e4296c68adb9d39dc99a0342e23cd6686b295d', }); - const outputs3 = [new Output(2000, p2pkhScript1)]; + const outputs3 = [new Output(2000n, p2pkhScript1)]; const tx3 = new Transaction([], outputs3, { version: 0, hash: '000164e1e7ec7700a18750f9f50a1a9b63f6c7268637c072ae9ee181e58eb01b', @@ -262,13 +361,13 @@ test('Known transactions hash', () => { ); expect(tx.inputs[0].index).toBe(1); expect(tx.outputs[0].value).toBe(100n); - expect(tx.outputs[0].decodedScript.timelock).toBeNull(); + expect(tx.outputs[0].decodedScript?.timelock).toBeNull(); expect(tx.outputs[0].tokenData).toBe(0); - expect(tx.outputs[0].decodedScript.address.base58).toBe('WURpMuhenPHPC7yLWk2LX9Hsuwr5r5JvdR'); + expect(tx.outputs[0].decodedScript?.address.base58).toBe('WURpMuhenPHPC7yLWk2LX9Hsuwr5r5JvdR'); expect(tx.outputs[1].value).toBe(23n); - expect(tx.outputs[1].decodedScript.timelock).toBeNull(); + expect(tx.outputs[1].decodedScript?.timelock).toBeNull(); expect(tx.outputs[1].tokenData).toBe(0); - expect(tx.outputs[1].decodedScript.address.base58).toBe('WURpMuhenPHPC7yLWk2LX9Hsuwr5r5JvdR'); + expect(tx.outputs[1].decodedScript?.address.base58).toBe('WURpMuhenPHPC7yLWk2LX9Hsuwr5r5JvdR'); expect(tx.weight).toBe(8.000001); expect(tx.timestamp).toBe(1625080359); expect(tx.parents.length).toBe(2); @@ -377,7 +476,7 @@ describe('NFT Validation', () => { expect.assertions(1); const historyTx = cloneNftSample(); - const txInstance = helpers.createTxFromHistoryObject(historyTx); + const txInstance = helpers.createTxFromHistoryObject(historyTx) as CreateTokenTransaction; expect(() => txInstance.validateNft(network)).not.toThrow(); }); @@ -388,7 +487,7 @@ describe('NFT Validation', () => { // Removing all outputs from index 1 onwards historyTx.outputs.length = 1; - const txInstance = helpers.createTxFromHistoryObject(historyTx); + const txInstance = helpers.createTxFromHistoryObject(historyTx) as CreateTokenTransaction; expect(() => txInstance.validateNft(network)).toThrow('minimum'); }); @@ -396,7 +495,7 @@ describe('NFT Validation', () => { it('should validate maximum outputs of a transaction', () => { expect.assertions(2); const historyTx = cloneNftSample(); - const txInstance = helpers.createTxFromHistoryObject(historyTx); + const txInstance = helpers.createTxFromHistoryObject(historyTx) as CreateTokenTransaction; // Adding outputs within allowed limit for (let i = 1; i < MAX_OUTPUTS; ++i) { diff --git a/__tests__/new/hathorwallet.test.ts b/__tests__/new/hathorwallet.test.ts index a816377cd..0f16ae619 100644 --- a/__tests__/new/hathorwallet.test.ts +++ b/__tests__/new/hathorwallet.test.ts @@ -27,6 +27,7 @@ import walletUtils from '../../src/utils/wallet'; import versionApi from '../../src/api/version'; import { decryptData, verifyMessage } from '../../src/utils/crypto'; import { WalletTxTemplateInterpreter, TransactionTemplate } from '../../src/template/transaction'; +import { mockGetToken } from '../__mock_helpers__/get-token.mock'; class FakeHathorWallet { constructor() { @@ -41,6 +42,10 @@ class FakeHathorWallet { } } +afterEach(() => { + jest.restoreAllMocks(); +}); + test('getFullTxById', async () => { const hWallet = new FakeHathorWallet(); @@ -976,6 +981,7 @@ describe('prepare transactions without signature', () => { selectUtxos: generateSelectUtxos(fakeTokenToDepositUtxo), }); jest.spyOn(hWallet, 'getMintAuthority').mockReturnValue(fakeMintAuthority); + jest.spyOn(hWallet.storage, 'getToken').mockImplementation(mockGetToken); // prepare mint const txData = await hWallet.prepareMintTokensData('01', 100n, { @@ -1021,6 +1027,7 @@ describe('prepare transactions without signature', () => { selectUtxos: generateSelectUtxos(fakeTokenToDepositUtxo), }); jest.spyOn(hWallet, 'getMintAuthority').mockReturnValue(fakeMintAuthority); + jest.spyOn(hWallet.storage, 'getToken').mockImplementation(mockGetToken); // prepare mint const txData = await hWallet.prepareMintTokensData('01', 100n, { @@ -1088,6 +1095,7 @@ describe('prepare transactions without signature', () => { selectUtxos: generateSelectUtxos({ ...fakeTokenToDepositUtxo, value: amountAvailable }), }); jest.spyOn(hWallet, 'getMintAuthority').mockReturnValue(fakeMintAuthority); + jest.spyOn(hWallet.storage, 'getToken').mockImplementation(mockGetToken); // prepare mint await expect( @@ -1096,7 +1104,7 @@ describe('prepare transactions without signature', () => { pinCode: '1234', signTx: false, // skip the signature }) - ).rejects.toThrow('Not enough HTR tokens for deposit: 10 required, 1 available'); + ).rejects.toThrow('Not enough HTR tokens for deposit or fee: 10 required, 1 available'); }); test('prepareMeltTokensData', async () => { @@ -1132,6 +1140,7 @@ describe('prepare transactions without signature', () => { selectUtxos: generateSelectUtxos(fakeTokenToMeltUtxo), }); jest.spyOn(hWallet, 'getMeltAuthority').mockReturnValue(fakeMeltAuthority); + jest.spyOn(hWallet.storage, 'getToken').mockImplementation(mockGetToken); // prepare melt const txData = await hWallet.prepareMeltTokensData('01', 100, { @@ -1187,6 +1196,7 @@ describe('prepare transactions without signature', () => { selectUtxos: generateSelectUtxos(fakeTokenToMeltUtxo), }); jest.spyOn(hWallet, 'getMeltAuthority').mockReturnValue(fakeMeltAuthority); + jest.spyOn(hWallet.storage, 'getToken').mockImplementation(mockGetToken); // prepare melt const txData = await hWallet.prepareMeltTokensData('01', 100, { @@ -1261,6 +1271,7 @@ describe('prepare transactions without signature', () => { hWallet.storage.selectUtxos.mockImplementationOnce(generateSelectUtxos(fakeTokenToMeltUtxo)); hWallet.storage.selectUtxos.mockImplementationOnce(generateSelectUtxos(fakeTokenToDepositUtxo)); jest.spyOn(hWallet, 'getMeltAuthority').mockReturnValue(fakeMeltAuthority); + jest.spyOn(hWallet.storage, 'getToken').mockImplementation(mockGetToken); // prepare melt const txData = await hWallet.prepareMeltTokensData('01', 100, { @@ -1342,11 +1353,15 @@ describe('prepare transactions without signature', () => { // wallet and mocks const hWallet = new FakeHathorWallet(); - hWallet.storage = getStorage({ + const storage = getStorage({ readOnly: false, currentAddress: fakeAddress.base58, selectUtxos: generateSelectUtxos(fakeTokenToMeltUtxo), }); + + jest.spyOn(storage, 'getToken').mockImplementation(mockGetToken); + + hWallet.storage = storage; jest.spyOn(hWallet, 'getMeltAuthority').mockReturnValue(fakeMeltAuthority); // prepare melt diff --git a/__tests__/new/sendTransaction.test.ts b/__tests__/new/sendTransaction.test.ts index 01314b99d..a15021bf9 100644 --- a/__tests__/new/sendTransaction.test.ts +++ b/__tests__/new/sendTransaction.test.ts @@ -15,6 +15,7 @@ import { MemoryStore, Storage } from '../../src/storage'; import { WalletType } from '../../src/types'; import transaction from '../../src/utils/transaction'; import { OutputType } from '../../src/wallet/types'; +import { mockGetToken } from '../__mock_helpers__/get-token.mock'; test('type methods', () => { // The ISendInput and ISendOutput were created to satisfy the old facade methods while using typescript @@ -77,6 +78,7 @@ test('prepareTxData', async () => { }) ); jest.spyOn(storage, 'isAddressMine').mockReturnValue(true); + const spyGetToken = jest.spyOn(storage, 'getToken').mockImplementation(mockGetToken); const preparedTx = { validate: jest.fn(), }; @@ -172,6 +174,7 @@ test('prepareTxData', async () => { await expect(sendTransaction.prepareTx()).resolves.toBe(preparedTx); prepareSpy.mockRestore(); + spyGetToken.mockRestore(); }); test('invalid method calls', async () => { diff --git a/__tests__/storage/common_store.test.ts b/__tests__/storage/common_store.test.ts index c16e2fb9d..3918b3a6e 100644 --- a/__tests__/storage/common_store.test.ts +++ b/__tests__/storage/common_store.test.ts @@ -7,7 +7,7 @@ import { MemoryStore, Storage } from '../../src/storage'; import { TOKEN_AUTHORITY_MASK, TOKEN_MINT_MASK, GAP_LIMIT } from '../../src/constants'; -import { ILockedUtxo, IStore, IUtxo, OutputValueType } from '../../src/types'; +import { ILockedUtxo, IStore, IUtxo, OutputValueType, TokenVersion } from '../../src/types'; describe('locked utxo methods', () => { const spyDate = jest.spyOn(Date, 'now'); @@ -181,7 +181,12 @@ describe('registered tokens', () => { async function testRegisteredTokens(store) { const storage = new Storage(store); - await storage.registerToken({ uid: 'abc1', name: 'test token 1', symbol: 'TST1' }); + await storage.registerToken({ + uid: 'abc1', + name: 'test token 1', + symbol: 'TST1', + version: TokenVersion.DEPOSIT, + }); await expect(storage.isTokenRegistered('abc1')).resolves.toEqual(true); await expect(storage.isTokenRegistered('abc2')).resolves.toEqual(false); } diff --git a/__tests__/storage/memory_store.test.ts b/__tests__/storage/memory_store.test.ts index cda4f10b0..01f0fa1a8 100644 --- a/__tests__/storage/memory_store.test.ts +++ b/__tests__/storage/memory_store.test.ts @@ -11,7 +11,7 @@ import { MemoryStore, Storage } from '../../src/storage'; import tx_history from '../__fixtures__/tx_history'; import walletApi from '../../src/api/wallet'; import { encryptData } from '../../src/utils/crypto'; -import { WalletType } from '../../src/types'; +import { TokenVersion, WalletType } from '../../src/types'; import { processHistory } from '../../src/utils/storage'; test('default values', async () => { @@ -164,12 +164,17 @@ test('token methods', async () => { // Starts empty expect(store.tokens.size).toEqual(0); - await store.saveToken({ uid: '01', name: 'Token 01', symbol: 'TK01' }); + await store.saveToken({ + uid: '01', + name: 'Token 01', + symbol: 'TK01', + version: TokenVersion.DEPOSIT, + }); expect(store.tokens.size).toEqual(1); expect(store.tokens.get('01')).toBeDefined(); expect(store.tokensMetadata.get('01')).toBeUndefined(); await store.saveToken( - { uid: '02', name: 'Token 02', symbol: 'TK02' }, + { uid: '02', name: 'Token 02', symbol: 'TK02', version: TokenVersion.DEPOSIT }, { numTransactions: 1, balance: { @@ -191,8 +196,18 @@ test('token methods', async () => { } expect(registered).toHaveLength(0); - await store.registerToken({ uid: '02', name: 'Token 02', symbol: 'TK02' }); - await store.registerToken({ uid: '03', name: 'Token 03', symbol: 'TK03' }); + await store.registerToken({ + uid: '02', + name: 'Token 02', + symbol: 'TK02', + version: TokenVersion.DEPOSIT, + }); + await store.registerToken({ + uid: '03', + name: 'Token 03', + symbol: 'TK03', + version: TokenVersion.DEPOSIT, + }); registered = []; for await (const token of store.registeredTokenIter()) { @@ -207,7 +222,7 @@ test('token methods', async () => { } expect(registered).toHaveLength(1); - await store.saveToken({ uid: '00', name: 'Hathor', symbol: 'HTR' }); + await store.saveToken({ uid: '00', name: 'Hathor', symbol: 'HTR', version: TokenVersion.NATIVE }); await store.editTokenMeta('00', { numTransactions: 10, balance: { tokens: { locked: 1n, unlocked: 2n } }, @@ -305,7 +320,12 @@ test('access data methods', async () => { // Clean storage but keep registered tokens await store.saveAddress({ base58: 'WYiD1E8n5oB9weZ8NMyM3KoCjKf1KCjWAZ', bip32AddressIndex: 0 }); await store.saveTx(tx_history[0]); - await store.registerToken({ uid: 'testtoken', name: 'Test token', symbol: 'TST' }); + await store.registerToken({ + uid: 'testtoken', + name: 'Test token', + symbol: 'TST', + version: TokenVersion.DEPOSIT, + }); expect(store.history.size).toEqual(1); expect(store.addresses.size).toEqual(1); expect(store.registeredTokens.size).toEqual(1); @@ -317,7 +337,12 @@ test('access data methods', async () => { // Clean only registered tokens await store.saveAddress({ base58: 'WYiD1E8n5oB9weZ8NMyM3KoCjKf1KCjWAZ', bip32AddressIndex: 0 }); await store.saveTx(tx_history[0]); - await store.registerToken({ uid: 'testtoken', name: 'Test token', symbol: 'TST' }); + await store.registerToken({ + uid: 'testtoken', + name: 'Test token', + symbol: 'TST', + version: TokenVersion.DEPOSIT, + }); expect(store.history.size).toEqual(1); expect(store.addresses.size).toEqual(1); expect(store.registeredTokens.size).toEqual(1); @@ -327,7 +352,12 @@ test('access data methods', async () => { expect(store.registeredTokens.size).toEqual(0); // Clean all - await store.registerToken({ uid: 'testtoken', name: 'Test token', symbol: 'TST' }); + await store.registerToken({ + uid: 'testtoken', + name: 'Test token', + symbol: 'TST', + version: TokenVersion.DEPOSIT, + }); expect(store.history.size).toEqual(1); expect(store.addresses.size).toEqual(1); expect(store.registeredTokens.size).toEqual(1); diff --git a/__tests__/storage/storage.test.ts b/__tests__/storage/storage.test.ts index 401190524..20fea5860 100644 --- a/__tests__/storage/storage.test.ts +++ b/__tests__/storage/storage.test.ts @@ -32,6 +32,7 @@ import { IUtxoId, OutputValueType, WALLET_FLAGS, + TokenVersion, } from '../../src/types'; describe('handleStop', () => { @@ -59,7 +60,12 @@ describe('handleStop', () => { return out; } const storage = new Storage(store); - const testToken = { uid: 'testtoken', name: 'Test token', symbol: 'TST' }; + const testToken = { + uid: 'testtoken', + name: 'Test token', + symbol: 'TST', + version: TokenVersion.DEPOSIT, + }; await storage.saveAccessData(accessData); await loadAddresses(0, 20, storage); await storage.addTx({ diff --git a/__tests__/template/transaction/instructions.test.ts b/__tests__/template/transaction/instructions.test.ts index 5ca24591f..3d6b834e7 100644 --- a/__tests__/template/transaction/instructions.test.ts +++ b/__tests__/template/transaction/instructions.test.ts @@ -29,6 +29,7 @@ import { UtxoSelectInstruction, getVariable, } from '../../../src/template/transaction/instructions'; +import { TokenVersion } from '../../../src/types'; describe('parsing variable references', () => { it('should validate template variable reference strings', () => { @@ -681,6 +682,7 @@ describe('should parse template instructions', () => { signalBits: 254, tokenName: 'foo', tokenSymbol: 'bar', + tokenVersion: TokenVersion.DEPOSIT, }).success ).toBe(true); // Parse with defaults @@ -690,6 +692,7 @@ describe('should parse template instructions', () => { }) ).toStrictEqual({ type: 'action/config', + tokenVersion: TokenVersion.DEPOSIT, }); // parse with template refs expect( @@ -699,6 +702,7 @@ describe('should parse template instructions', () => { signalBits: '{signalBitsKey}', tokenName: '{tokenNameKey}', tokenSymbol: '{tokenSymbolKey}', + tokenVersion: '{tokenVersionKey}', }) ).toStrictEqual({ type: 'action/config', @@ -706,6 +710,7 @@ describe('should parse template instructions', () => { signalBits: '{signalBitsKey}', tokenName: '{tokenNameKey}', tokenSymbol: '{tokenSymbolKey}', + tokenVersion: '{tokenVersionKey}', }); // Error cases expect( diff --git a/__tests__/utils/fee.test.ts b/__tests__/utils/fee.test.ts new file mode 100644 index 000000000..b800bdf82 --- /dev/null +++ b/__tests__/utils/fee.test.ts @@ -0,0 +1,141 @@ +/** + * Copyright (c) Hathor Labs and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { + FEE_PER_OUTPUT, + NATIVE_TOKEN_UID, + TOKEN_AUTHORITY_MASK, + TOKEN_MELT_MASK, + TOKEN_MINT_MASK, +} from '../../src/constants'; +import { Fee } from '../../src/utils/fee'; +import Output from '../../src/models/output'; +import { MemoryStore, Storage } from '../../src/storage'; +import { IDataInput, IStorage, OutputValueType } from '../../src/types'; +import tokens from '../../src/utils/tokens'; +import { OutputType } from '../../src/wallet/types'; +import { mockGetToken } from '../__mock_helpers__/get-token.mock'; + +type Inputs = { [key: string]: { [key: string]: Partial } }; +describe('Fee test suite', () => { + let storage: IStorage; + const mockTokenInputs = (tokenUid: string) => ({ + swap: { + authorities: 0n, + token: tokenUid, + value: 100n, + data: '1', + }, + mint: { + authorities: 1n, + token: tokenUid, + value: 1n, + data: (TOKEN_MINT_MASK & 1n).toString(), + }, + melt: { + authorities: 2n, + token: tokenUid, + value: 2n, + data: (TOKEN_MELT_MASK & 1n).toString(), + }, + }); + const mockTokenOutput = (tokenUid: string, value: OutputValueType, authorities: bigint = 0n) => ({ + type: OutputType.P2PKH, + token: tokenUid, + value, + authorities, + }); + + const inputs: Inputs = { + htr: mockTokenInputs(NATIVE_TOKEN_UID), + // deposit based token + dbt: mockTokenInputs('dbt'), + // fee based token + fbt: mockTokenInputs('fbt'), + }; + + beforeEach(() => { + const store = new MemoryStore(); + storage = new Storage(store); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('should calculate fee for create token transaction', async () => { + // Arrange + const outputs = [ + new Output(TOKEN_MINT_MASK, Buffer.from('asdasdas'), { + tokenData: TOKEN_AUTHORITY_MASK + 1, + }), + new Output(10n, Buffer.from('asdasdas'), { + tokenData: 1, + }), + ]; + const expectedFee = FEE_PER_OUTPUT; + // Act + const fee = Fee.calculateTokenCreationTxFee(outputs); + + // Assert + expect(fee).toStrictEqual(expectedFee); + }); + + it('should ignore deposit based tokens and HTR', async () => { + // Arrange + const _inputs = [inputs.dbt.swap, inputs.dbt.mint, inputs.dbt.melt, inputs.htr.swap]; + + const _outputs = [ + mockTokenOutput('dbt', 100n), + mockTokenOutput(NATIVE_TOKEN_UID, inputs.htr.swap.value!), + ]; + jest.spyOn(storage, 'getToken').mockImplementation(mockGetToken); + + // Act + const ids = new Set(_inputs.concat(_outputs).map(el => el.token!)); + const _tokens = await tokens.getTokensByManyIds(storage, ids); + const fee = await Fee.calculate(_inputs as never, _outputs as never, _tokens); + + // Assert + expect(fee).toStrictEqual(0n); + }); + + it('should charge fee when melting without outputs', async () => { + // Arrange + const _inputs = [inputs.fbt.melt, inputs.fbt.swap]; + const _outputs = []; + jest.spyOn(storage, 'getToken').mockImplementation(mockGetToken); + + // Act + const ids = new Set(_inputs.concat(_outputs).map(el => el.token!)); + const _tokens = await tokens.getTokensByManyIds(storage, ids); + const fee = await Fee.calculate(_inputs as never, _outputs as never, _tokens); + + // Assert + expect(fee).toStrictEqual(FEE_PER_OUTPUT); + }); + + it('should charge fee based on the number of outputs', async () => { + // Arrange + const _inputs = [inputs.fbt.mint, inputs.fbt.swap, inputs.htr.swap]; + const _outputs = [ + mockTokenOutput('fbt', 100n), + mockTokenOutput('fbt', 100n), + mockTokenOutput('fbt', 100n), + mockTokenOutput('fbt', 1n, 1n), + ]; + jest.spyOn(storage, 'getToken').mockImplementation(mockGetToken); + + // Act + const ids = new Set(_inputs.concat(_outputs).map(el => el.token!)); + const _tokens = await tokens.getTokensByManyIds(storage, ids); + const fee = await Fee.calculate(_inputs as never, _outputs as never, _tokens); + + // Assert + expect(fee).toStrictEqual(3n * FEE_PER_OUTPUT); + }); +}); diff --git a/__tests__/utils/storage.test.ts b/__tests__/utils/storage.test.ts index d646e1ff6..6e342a1dd 100644 --- a/__tests__/utils/storage.test.ts +++ b/__tests__/utils/storage.test.ts @@ -7,7 +7,7 @@ import MockAdapter from 'axios-mock-adapter'; import axios from 'axios'; -import { HistorySyncMode, WalletType } from '../../src/types'; +import { HistorySyncMode, WalletType, TokenVersion } from '../../src/types'; import { MemoryStore, Storage } from '../../src/storage'; import { scanPolicyStartAddresses, @@ -126,6 +126,7 @@ describe('_updateTokensData', () => { uid: 'mock-token', name: 'Mock Token 1', symbol: 'MT1', + version: TokenVersion.DEPOSIT, }; const store = new MemoryStore(); const storage = new Storage(store); @@ -133,6 +134,7 @@ describe('_updateTokensData', () => { success: true, name: mockToken.name, symbol: mockToken.symbol, + version: mockToken.version, mint: [], melt: [], total: 0, @@ -152,6 +154,7 @@ describe('_updateTokensData', () => { name: mockToken.name, symbol: mockToken.symbol, uid: mockToken.uid, + version: mockToken.version, }); }); @@ -161,6 +164,7 @@ describe('_updateTokensData', () => { uid: 'mock-token', name: 'Mock Token 1', symbol: 'MT1', + version: TokenVersion.DEPOSIT, }; const store = new MemoryStore(); const storage = new Storage(store); @@ -181,6 +185,7 @@ describe('_updateTokensData', () => { success: true, name: mockToken.name, symbol: mockToken.symbol, + version: mockToken.version, mint: [], melt: [], total: 0, @@ -208,6 +213,7 @@ describe('_updateTokensData', () => { name: mockToken.name, symbol: mockToken.symbol, uid: mockToken.uid, + version: mockToken.version, }); }); @@ -387,6 +393,7 @@ test('addCreatedTokenFromTx', async () => { uid: 'd00d', name: 'Token A', symbol: 'tkA', + version: 1, }); await expect(storage.getToken('d00d')).resolves.not.toBeNull(); }); diff --git a/__tests__/utils/tokens.test.ts b/__tests__/utils/tokens.test.ts index 84fe9413b..7801ec2a0 100644 --- a/__tests__/utils/tokens.test.ts +++ b/__tests__/utils/tokens.test.ts @@ -10,6 +10,7 @@ import { NATIVE_TOKEN_UID } from '../../src/constants'; import walletApi from '../../src/api/wallet'; import { MemoryStore, Storage } from '../../src/storage'; import { TokenValidationError } from '../../src/errors'; +import { TokenVersion } from '../../src/types'; test('Validate configuration string', async () => { const uid = '0000360f5e95c492352a6f1cab81b33d56694299f1da2b437107b2b1edde9687'; @@ -35,17 +36,17 @@ test('Validate configuration string', async () => { // Should throw if uid does not match the expected uid await expect( - tokens.validateTokenToAddByConfigurationString(configString, null, 'expected-uid') + tokens.validateTokenToAddByConfigurationString(configString, undefined, 'expected-uid') ).rejects.toThrow('Configuration string uid does not match'); await expect( - tokens.validateTokenToAddByConfigurationString(configString, null, 'expected-uid') + tokens.validateTokenToAddByConfigurationString(configString, undefined, 'expected-uid') ).rejects.toThrow(TokenValidationError); await expect( tokens.validateTokenToAddByConfigurationString(configString, storage, 'expected-uid') ).rejects.toThrow(TokenValidationError); // should throw if token is already registered - await store.registerToken({ uid, name, symbol }); + await store.registerToken({ uid, name, symbol, version: TokenVersion.DEPOSIT }); await expect( tokens.validateTokenToAddByConfigurationString(configString, storage) ).rejects.toThrow('You already have this token'); @@ -55,7 +56,12 @@ test('Validate configuration string', async () => { await store.unregisterToken(uid); // Should throw if we have a similarly named token - await store.registerToken({ uid: uid2, name: 'Test Token', symbol: 'TST2' }); + await store.registerToken({ + uid: uid2, + name: 'Test Token', + symbol: 'TST2', + version: TokenVersion.DEPOSIT, + }); await expect( tokens.validateTokenToAddByConfigurationString(configString, storage) ).rejects.toThrow('You already have a token with this name'); @@ -64,7 +70,12 @@ test('Validate configuration string', async () => { ).rejects.toThrow(TokenValidationError); await store.unregisterToken(uid2); - await store.registerToken({ uid: uid2, name: 'Another test name', symbol: 'TST' }); + await store.registerToken({ + uid: uid2, + name: 'Another test name', + symbol: 'TST', + version: TokenVersion.DEPOSIT, + }); await expect( tokens.validateTokenToAddByConfigurationString(configString, storage) ).rejects.toThrow('You already have a token with this symbol'); @@ -107,7 +118,7 @@ test('Validate configuration string', async () => { // With no conflicts in storage and the api confirming the token is valid // we expect the token data to be returned apiSpy.mockImplementation((_, cb) => { - cb({ success: true, name, symbol }); + cb({ success: true, name, symbol, version: TokenVersion.DEPOSIT }); }); await expect( tokens.validateTokenToAddByConfigurationString(configString, storage) @@ -127,17 +138,18 @@ test('Configuration String', () => { expect(tokens.isConfigurationStringValid(configString)).toBe(true); const tokenObj = tokens.getTokenFromConfigurationString(configString); - expect(tokenObj.uid).toBe(uid); - expect(tokenObj.name).toBe(name); - expect(tokenObj.symbol).toBe(symbol); + expect(tokenObj).not.toBeNull(); + expect(tokenObj!.uid).toBe(uid); + expect(tokenObj!.name).toBe(name); + expect(tokenObj!.symbol).toBe(symbol); expect(tokens.getConfigurationString(uid, name, symbol)).toBe(configString); }); test('Token index', () => { const configs = [ - { uid: 'a', name: 'b', symbol: 'c' }, - { uid: 'd', name: 'e', symbol: 'f' }, + { uid: 'a', name: 'b', symbol: 'c', version: TokenVersion.DEPOSIT }, + { uid: 'd', name: 'e', symbol: 'f', version: TokenVersion.DEPOSIT }, ]; expect(tokens.getTokenIndex(configs, NATIVE_TOKEN_UID)).toBe(0); expect(tokens.getTokenIndex(configs, 'a')).toBe(1); diff --git a/__tests__/utils/transaction.test.ts b/__tests__/utils/transaction.test.ts index 7fac5497e..572e7b01b 100644 --- a/__tests__/utils/transaction.test.ts +++ b/__tests__/utils/transaction.test.ts @@ -27,6 +27,7 @@ import Output from '../../src/models/output'; import P2PKH from '../../src/models/p2pkh'; import Address from '../../src/models/address'; import NanoContractHeader from '../../src/nano_contracts/header'; +import { TokenVersion } from '../../src/types'; test('isAuthorityOutput', () => { expect(transaction.isAuthorityOutput({ token_data: TOKEN_AUTHORITY_MASK })).toBe(true); @@ -620,7 +621,9 @@ test('convertTransactionToHistoryTx', async () => { spent_by: null, }, ], - tokens: [{ uid: 'token-B', name: 'Token B', symbol: 'TKB' }], + tokens: [ + { uid: 'token-B', name: 'Token B', symbol: 'TKB', version: TokenVersion.DEPOSIT }, + ], inputs: [], nonce: '', timestamp: 0, diff --git a/__tests__/wallet/api/walletApi.test.ts b/__tests__/wallet/api/walletApi.test.ts index 9c02eb517..6b393a738 100644 --- a/__tests__/wallet/api/walletApi.test.ts +++ b/__tests__/wallet/api/walletApi.test.ts @@ -195,6 +195,7 @@ describe('walletApi', () => { id: '0000000000000000000000000000000000000000000000000000000000000001', name: 'Token 1', symbol: 'TK1', + version: 1, // TokenVersion.DEPOSIT }, totalSupply: 1000n, totalTransactions: 5, @@ -230,6 +231,7 @@ describe('walletApi', () => { id: '0000000000000000000000000000000000000000000000000000000000000002', name: 'Token 1', symbol: 'TK1', + version: 1, // TokenVersion.DEPOSIT }, balance: { unlocked: 100n, diff --git a/__tests__/wallet/wallet.test.ts b/__tests__/wallet/wallet.test.ts index 93c885f74..f983c288d 100644 --- a/__tests__/wallet/wallet.test.ts +++ b/__tests__/wallet/wallet.test.ts @@ -27,6 +27,7 @@ import { SendTxError, UninitializedWalletError, WalletRequestError, + UtxoError, } from '../../src/errors'; import SendTransactionWalletService from '../../src/wallet/sendTransactionWalletService'; import transaction from '../../src/utils/transaction'; @@ -34,12 +35,15 @@ import { TOKEN_MELT_MASK, TOKEN_MINT_MASK, WALLET_SERVICE_AUTH_DERIVATION_PATH, + NATIVE_TOKEN_UID, } from '../../src/constants'; import { MemoryStore, Storage } from '../../src/storage'; import walletApi from '../../src/wallet/api/walletApi'; import walletUtils from '../../src/utils/wallet'; import { decryptData, verifyMessage } from '../../src/utils/crypto'; -import { IHistoryTx, IWalletAccessData } from '../../src/types'; +import { IHistoryTx, IWalletAccessData, TokenVersion } from '../../src/types'; +import { mockGetToken } from '../__mock_helpers__/get-token.mock'; +import { Fee } from '../../src/utils/fee'; // Mock SendTransactionWalletService class so we don't try to send actual transactions // TODO: We should refactor the way we use classes from inside other classes. Using dependency injection would facilitate unit tests a lot and avoid mocks like this. @@ -87,6 +91,155 @@ afterEach(() => { jest.clearAllMocks(); }); +/** + * Helper functions to setup mocks for fee token tests + */ +const setupFeeTokenMocks = { + /** + * Setup API mocks for fee token operations (mint/melt) + * @param addresses - Array of addresses + * @param tokenId - Token ID + * @param authorityMask - Authority mask (TOKEN_MINT_MASK or TOKEN_MELT_MASK) + * @param tokenName - Token name (default: 'Fee Token') + * @param tokenSymbol - Token symbol (default: 'FBT') + */ + setupApiMocks: ( + addresses: string[], + tokenId: string, + authorityMask: bigint, + tokenName = 'Fee Token', + tokenSymbol = 'FBT' + ) => { + mockAxiosAdapter.onPost('wallet/addresses/check_mine').reply(200, { + success: true, + addresses: { + [addresses[2]]: true, + }, + }); + + jest.spyOn(walletApi, 'getAddressDetails').mockResolvedValue({ + data: { + index: 2, + address: addresses[2], + transactions: 0, + seqnum: 0, + }, + }); + + jest.spyOn(walletApi, 'getTxOutputs').mockResolvedValue({ + success: true, + txOutputs: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + tokenId, + address: addresses[2], + value: authorityMask, + authorities: authorityMask, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/2", + }, + ], + }); + + jest.spyOn(walletApi, 'getTokenDetails').mockResolvedValue({ + success: true, + name: tokenName, + symbol: tokenSymbol, + version: TokenVersion.FEE, + }); + }, + + /** + * Setup wallet mocks for fee token operations + * @param wallet - Wallet instance + * @param seed - Wallet seed + * @param network - Network instance + * @param tokenId - Token ID + * @param authorityType - 'mint' or 'melt' + * @param addresses - Array of addresses + * @param tokenName - Token name (default: 'Fee Token') + * @param tokenSymbol - Token symbol (default: 'FBT') + */ + setupWalletMocks: ( + wallet: HathorWalletServiceWallet, + seed: string, + network: Network, + tokenId: string, + authorityType: 'mint' | 'melt', + addresses: string[], + tokenName = 'Fee Token', + tokenSymbol = 'FBT' + ) => { + const code = new Mnemonic(seed); + const xpriv = code.toHDPrivateKey('', network.getNetwork()); + const authorityMask = authorityType === 'mint' ? TOKEN_MINT_MASK : TOKEN_MELT_MASK; + + jest.spyOn(wallet.storage, 'getMainXPrivKey').mockReturnValue(Promise.resolve(xpriv.xprivkey)); + jest.spyOn(wallet, 'getInputData').mockImplementation(() => Buffer.alloc(0)); + jest.spyOn(wallet.storage, 'getToken').mockImplementation(mockGetToken); + jest.spyOn(wallet, 'getAddressIndex').mockResolvedValue(0); + jest.spyOn(wallet, 'getTokenDetails').mockResolvedValue({ + tokenInfo: { + id: tokenId, + name: tokenName, + symbol: tokenSymbol, + version: TokenVersion.FEE, + }, + totalSupply: 1000n, + totalTransactions: 1, + authorities: { + mint: authorityType === 'mint', + melt: authorityType === 'melt', + }, + }); + + if (authorityType === 'mint') { + jest.spyOn(wallet, 'getMintAuthority').mockResolvedValue([ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + address: addresses[2], + authorities: authorityMask, + }, + ]); + } else { + jest.spyOn(wallet, 'getMeltAuthority').mockResolvedValue([ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + address: addresses[2], + authorities: authorityMask, + }, + ]); + } + }, + + /** + * Setup complete mocks for fee token tests (API + Wallet) + * @param wallet - Wallet instance + * @param seed - Wallet seed + * @param network - Network instance + * @param tokenId - Token ID + * @param authorityType - 'mint' or 'melt' + * @param addresses - Array of addresses + */ + setupCompleteMocks: ( + wallet: HathorWalletServiceWallet, + seed: string, + network: Network, + tokenId: string, + authorityType: 'mint' | 'melt', + addresses: string[] + ) => { + const authorityMask = authorityType === 'mint' ? TOKEN_MINT_MASK : TOKEN_MELT_MASK; + setupFeeTokenMocks.setupApiMocks(addresses, tokenId, authorityMask); + setupFeeTokenMocks.setupWalletMocks(wallet, seed, network, tokenId, authorityType, addresses); + }, +}; + test('getAddressAtIndex', async () => { const requestPassword = jest.fn(); const network = new Network('testnet'); @@ -827,6 +980,13 @@ test('prepareMintTokens', async () => { .spyOn(wallet.storage, 'getMainXPrivKey') .mockReturnValue(Promise.resolve(xpriv.xprivkey)); const spy3 = jest.spyOn(wallet, 'getInputData').mockImplementation(getInputDataMock); + jest.spyOn(wallet.storage, 'getToken').mockImplementation(mockGetToken); + jest.spyOn(wallet, 'getTokenDetails').mockImplementation(async token => { + const { uid, ...mockData } = await mockGetToken(token); + return { + tokenInfo: { id: uid, ...mockData }, + }; + }); // error because of wrong authority output address await expect( @@ -900,6 +1060,252 @@ test('prepareMintTokens', async () => { spy3.mockRestore(); }); +test('prepareMintTokensData - fee token without enough HTR', async () => { + const addresses = [ + 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', + 'WbjNdAGBWAkCS2QVpqmacKXNy8WVXatXNM', + 'WR1i8USJWQuaU423fwuFQbezfevmT4vFWX', + ]; + + mockAxiosAdapter.onPost('wallet/addresses/check_mine').reply(200, { + success: true, + addresses: { + [addresses[2]]: true, + }, + }); + + jest.spyOn(walletApi, 'getAddressDetails').mockResolvedValue({ + data: { + index: 2, + address: addresses[2], + transactions: 0, + seqnum: 0, + }, + }); + + jest.spyOn(walletApi, 'getTxOutputs').mockResolvedValue({ + success: true, + txOutputs: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + tokenId: 'fbt', + address: addresses[2], + value: TOKEN_MINT_MASK, + authorities: TOKEN_MINT_MASK, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/2", + }, + ], + }); + + jest.spyOn(walletApi, 'getTokenDetails').mockResolvedValue({ + success: true, + name: 'Fee Token', + symbol: 'FBT', + version: TokenVersion.FEE, + }); + + const requestPassword = jest.fn(); + const network = new Network('testnet'); + const seed = + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff'; + const wallet = new HathorWalletServiceWallet({ + requestPassword, + seed, + network, + passphrase: '', + xpriv: null, + xpub: null, + }); + wallet.setState('Ready'); + + const code = new Mnemonic(seed); + const xpriv = code.toHDPrivateKey('', network.getNetwork()); + + jest.spyOn(wallet.storage, 'getMainXPrivKey').mockReturnValue(Promise.resolve(xpriv.xprivkey)); + jest.spyOn(wallet, 'getInputData').mockImplementation(() => Buffer.alloc(0)); + jest.spyOn(wallet.storage, 'getToken').mockImplementation(mockGetToken); + jest.spyOn(wallet, 'getAddressIndex').mockResolvedValue(0); + jest.spyOn(wallet, 'getTokenDetails').mockResolvedValue({ + tokenInfo: { + id: 'fbt', + name: 'Fee Token', + symbol: 'FBT', + version: TokenVersion.FEE, + }, + totalSupply: 1000n, + totalTransactions: 1, + authorities: { + mint: true, + melt: false, + }, + }); + jest.spyOn(wallet, 'getMintAuthority').mockResolvedValue([ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + address: addresses[2], + authorities: TOKEN_MINT_MASK, + }, + ]); + + const _spyGetUtxos = jest.spyOn(wallet, 'getUtxos').mockImplementation(async () => ({ + utxos: [], + changeAmount: 0n, + })); + const _spyGetUtxosForAmount = jest + .spyOn(wallet, 'getUtxosForAmount') + .mockImplementation(async () => ({ + utxos: [], + changeAmount: 0n, + })); + + await expect( + wallet.prepareMintTokensData('fbt', 100n, { + address: addresses[1], + createAnotherMint: true, + mintAuthorityAddress: addresses[2], + pinCode: '123456', + }) + ).rejects.toThrow(UtxoError); + + _spyGetUtxos.mockRestore(); + _spyGetUtxosForAmount.mockRestore(); +}); + +test('prepareMintTokensData - fee token with change, mint, and melt authority outputs', async () => { + const addresses = [ + 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', + 'WbjNdAGBWAkCS2QVpqmacKXNy8WVXatXNM', + 'WR1i8USJWQuaU423fwuFQbezfevmT4vFWX', + ]; + + const requestPassword = jest.fn(); + const network = new Network('testnet'); + const seed = + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff'; + const wallet = new HathorWalletServiceWallet({ + requestPassword, + seed, + network, + passphrase: '', + xpriv: null, + xpub: null, + }); + wallet.setState('Ready'); + + // Setup fee token mocks + setupFeeTokenMocks.setupCompleteMocks(wallet, seed, network, '02', 'mint', addresses); + jest + .spyOn(wallet, 'checkAddressesMine') + .mockReturnValue(Promise.resolve({ [addresses[2]]: true })); + + jest.spyOn(wallet, 'getUtxos').mockImplementation(async params => { + if (params?.tokenId === NATIVE_TOKEN_UID) { + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: NATIVE_TOKEN_UID, + address: addresses[0], + value: 10n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 9n, + }; + } + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: '02', + address: addresses[0], + value: 1n, + authorities: params?.authority || 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 0n, + }; + }); + + jest.spyOn(wallet, 'getUtxosForAmount').mockImplementation(async (amount, params) => { + if (params?.token === NATIVE_TOKEN_UID) { + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: NATIVE_TOKEN_UID, + address: addresses[0], + value: 10n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 9n, + }; + } + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: '02', + address: addresses[0], + value: 1n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 0n, + }; + }); + + const result = await wallet.prepareMintTokensData('02', 1000n, { + address: addresses[1], + createAnotherMint: true, + mintAuthorityAddress: addresses[2], + changeAddress: addresses[2], + pinCode: '123456', + signTx: false, + }); + + expect(result.inputs).toEqual([ + expect.objectContaining({ data: expect.any(Object) }), + expect.objectContaining({ data: expect.any(Object) }), + ]); + + expect(result.outputs).toHaveLength(3); + const authorityOutputs = result.outputs.filter(o => + transaction.isAuthorityOutput({ token_data: o.tokenData }) + ); + expect(authorityOutputs).toHaveLength(1); + expect(authorityOutputs[0].value).toEqual(TOKEN_MINT_MASK); + + const p2pkhMint = authorityOutputs[0].parseScript(network); + expect(p2pkhMint.address.base58).toBe(addresses[2]); +}); + test('prepareMeltTokens', async () => { const addresses = [ 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', @@ -1002,6 +1408,7 @@ test('prepareMeltTokens', async () => { .spyOn(wallet.storage, 'getMainXPrivKey') .mockReturnValue(Promise.resolve(xpriv.xprivkey)); const spy3 = jest.spyOn(wallet, 'getInputData').mockImplementation(getInputDataMock); + jest.spyOn(wallet.storage, 'getToken').mockImplementation(mockGetToken); // error because of wrong authority output address await expect( @@ -1075,7 +1482,7 @@ test('prepareMeltTokens', async () => { spy3.mockRestore(); }); -test('prepareDelegateAuthorityData', async () => { +test('prepareMeltTokensData - fee token without enough HTR', async () => { const addresses = [ 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', 'WbjNdAGBWAkCS2QVpqmacKXNy8WVXatXNM', @@ -1085,35 +1492,44 @@ test('prepareDelegateAuthorityData', async () => { mockAxiosAdapter.onPost('wallet/addresses/check_mine').reply(200, { success: true, addresses: { - WR1i8USJWQuaU423fwuFQbezfevmT4vFWX: true, + [addresses[2]]: true, }, }); - // Mock getAddressDetails for address index resolution jest.spyOn(walletApi, 'getAddressDetails').mockResolvedValue({ data: { index: 2, address: addresses[2], + transactions: 0, + seqnum: 0, }, }); jest.spyOn(walletApi, 'getTxOutputs').mockResolvedValue({ + success: true, txOutputs: [ { txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', index: 0, - tokenId: '01', + tokenId: 'fbt', address: addresses[2], - value: 1n, - authorities: TOKEN_MINT_MASK, + value: TOKEN_MELT_MASK, + authorities: TOKEN_MELT_MASK, timelock: null, heightlock: null, locked: false, - addressPath: "m/44'/280'/0'/0/2", + addressPath: "m/280'/280'/0/1/2", }, ], }); + jest.spyOn(walletApi, 'getTokenDetails').mockResolvedValue({ + success: true, + name: 'Fee Token', + symbol: 'FBT', + version: TokenVersion.FEE, + }); + const requestPassword = jest.fn(); const network = new Network('testnet'); const seed = @@ -1126,28 +1542,359 @@ test('prepareDelegateAuthorityData', async () => { xpriv: null, xpub: null, }); + wallet.setState('Ready'); const code = new Mnemonic(seed); const xpriv = code.toHDPrivateKey('', network.getNetwork()); - wallet.setState('Ready'); - - const getUtxosMock = async () => ({ - utxos: [ - { - txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', - index: 0, - tokenId: '00', - address: addresses[0], - value: 1n, - authorities: 1n, - timelock: null, - heightlock: null, - locked: false, - addressPath, - }, - ], - changeAmount: 4n, + jest.spyOn(wallet.storage, 'getMainXPrivKey').mockReturnValue(Promise.resolve(xpriv.xprivkey)); + jest.spyOn(wallet, 'getInputData').mockImplementation(() => Buffer.alloc(0)); + jest.spyOn(wallet.storage, 'getToken').mockImplementation(mockGetToken); + jest.spyOn(wallet, 'getAddressIndex').mockResolvedValue(0); + jest.spyOn(wallet, 'getTokenDetails').mockResolvedValue({ + tokenInfo: { + id: 'fbt', + name: 'Fee Token', + symbol: 'FBT', + version: TokenVersion.FEE, + }, + totalSupply: 1000n, + totalTransactions: 1, + authorities: { + mint: false, + melt: true, + }, + }); + jest.spyOn(wallet, 'getMeltAuthority').mockResolvedValue([ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + address: addresses[2], + authorities: TOKEN_MELT_MASK, + }, + ]); + + const _spyGetUtxos = jest.spyOn(wallet, 'getUtxos').mockImplementation(async () => ({ + utxos: [], + changeAmount: 0n, + })); + const _spyGetUtxosForAmount = jest + .spyOn(wallet, 'getUtxosForAmount') + .mockImplementation(async (amount, params) => { + // Return tokens for melting + if (params?.token === 'fbt') { + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: 'fbt', + address: addresses[0], + value: 100n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 0n, + }; + } + // Return empty for HTR (to trigger the error) + return { + utxos: [], + changeAmount: 0n, + }; + }); + + await expect( + wallet.prepareMeltTokensData('fbt', 100n, { + address: addresses[1], + createAnotherMint: true, + meltAuthorityAddress: addresses[2], + pinCode: '123456', + }) + ).rejects.toThrow(UtxoError); + + _spyGetUtxos.mockRestore(); + _spyGetUtxosForAmount.mockRestore(); +}); + +test('prepareMeltTokensData - fee token with change and melt authority outputs', async () => { + const addresses = [ + 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', + 'WbjNdAGBWAkCS2QVpqmacKXNy8WVXatXNM', + 'WR1i8USJWQuaU423fwuFQbezfevmT4vFWX', + ]; + + mockAxiosAdapter.onPost('wallet/addresses/check_mine').reply(200, { + success: true, + addresses: { + [addresses[2]]: true, + }, + }); + + jest.spyOn(walletApi, 'getAddressDetails').mockResolvedValue({ + data: { + index: 2, + address: addresses[2], + transactions: 0, + seqnum: 0, + }, + }); + + jest.spyOn(walletApi, 'getTxOutputs').mockResolvedValue({ + success: true, + txOutputs: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + tokenId: '02', + address: addresses[2], + value: TOKEN_MELT_MASK, + authorities: TOKEN_MELT_MASK, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/2", + }, + ], + }); + + jest.spyOn(walletApi, 'getTokenDetails').mockResolvedValue({ + success: true, + name: 'Fee Token', + symbol: 'FBT', + version: TokenVersion.FEE, + }); + + const requestPassword = jest.fn(); + const network = new Network('testnet'); + const seed = + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff'; + const wallet = new HathorWalletServiceWallet({ + requestPassword, + seed, + network, + passphrase: '', + xpriv: null, + xpub: null, + }); + wallet.setState('Ready'); + + jest.spyOn(wallet, 'getUtxos').mockImplementation(async params => { + if (params?.tokenId === NATIVE_TOKEN_UID) { + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: NATIVE_TOKEN_UID, + address: addresses[0], + value: 10n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 9n, + }; + } + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: '02', + address: addresses[0], + value: 2000n, + authorities: params?.authority || 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 1000n, + }; + }); + + jest.spyOn(wallet, 'getUtxosForAmount').mockImplementation(async (amount, params) => { + if (params?.token === '00') { + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: NATIVE_TOKEN_UID, + address: addresses[0], + value: 10n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 9n, + }; + } + return { + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: '02', + address: addresses[0], + value: amount, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: params?.token === '02' ? 1000n : 0n, + }; + }); + + const code = new Mnemonic( + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff' + ); + const xpriv = code.toHDPrivateKey('', network.getNetwork()); + + jest.spyOn(wallet.storage, 'getMainXPrivKey').mockReturnValue(Promise.resolve(xpriv.xprivkey)); + jest.spyOn(wallet, 'getInputData').mockImplementation(() => Buffer.alloc(0)); + jest.spyOn(wallet.storage, 'getToken').mockImplementation(mockGetToken); + jest + .spyOn(wallet, 'checkAddressesMine') + .mockReturnValue(Promise.resolve({ [addresses[2]]: true })); + jest.spyOn(wallet, 'getTokenDetails').mockResolvedValue({ + tokenInfo: { + id: '02', + name: 'Fee Token', + symbol: 'FBT', + version: TokenVersion.FEE, + }, + totalSupply: 1000n, + totalTransactions: 1, + authorities: { + mint: false, + melt: true, + }, + }); + jest.spyOn(wallet, 'getAddressIndex').mockResolvedValue(0); + jest.spyOn(wallet, 'getMeltAuthority').mockResolvedValue([ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + address: addresses[2], + authorities: TOKEN_MELT_MASK, + }, + ]); + + const result = await wallet.prepareMeltTokensData('02', 1000n, { + address: addresses[1], + createAnotherMint: true, + meltAuthorityAddress: addresses[2], + changeAddress: addresses[2], + pinCode: '123456', + signTx: false, + }); + + expect(result.inputs).toEqual([ + expect.objectContaining({ data: expect.any(Object) }), + expect.objectContaining({ data: expect.any(Object) }), + expect.objectContaining({ data: expect.any(Object) }), + ]); + + expect(result.outputs).toHaveLength(3); + const authorityOutputs = result.outputs.filter(o => + transaction.isAuthorityOutput({ token_data: o.tokenData }) + ); + expect(authorityOutputs).toHaveLength(1); + expect(authorityOutputs[0].value).toEqual(TOKEN_MELT_MASK); + + const p2pkhMelt = authorityOutputs[0].parseScript(network); + expect(p2pkhMelt.address.base58).toBe(addresses[2]); +}); + +test('prepareDelegateAuthorityData', async () => { + const addresses = [ + 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', + 'WbjNdAGBWAkCS2QVpqmacKXNy8WVXatXNM', + 'WR1i8USJWQuaU423fwuFQbezfevmT4vFWX', + ]; + + mockAxiosAdapter.onPost('wallet/addresses/check_mine').reply(200, { + success: true, + addresses: { + WR1i8USJWQuaU423fwuFQbezfevmT4vFWX: true, + }, + }); + + // Mock getAddressDetails for address index resolution + jest.spyOn(walletApi, 'getAddressDetails').mockResolvedValue({ + data: { + index: 2, + address: addresses[2], + }, + }); + + jest.spyOn(walletApi, 'getTxOutputs').mockResolvedValue({ + txOutputs: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + tokenId: '01', + address: addresses[2], + value: 1n, + authorities: TOKEN_MINT_MASK, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/44'/280'/0'/0/2", + }, + ], + }); + + const requestPassword = jest.fn(); + const network = new Network('testnet'); + const seed = + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff'; + const wallet = new HathorWalletServiceWallet({ + requestPassword, + seed, + network, + passphrase: '', + xpriv: null, + xpub: null, + }); + + const code = new Mnemonic(seed); + const xpriv = code.toHDPrivateKey('', network.getNetwork()); + + wallet.setState('Ready'); + + const getUtxosMock = async () => ({ + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5f', + index: 0, + tokenId: '00', + address: addresses[0], + value: 1n, + authorities: 1n, + timelock: null, + heightlock: null, + locked: false, + addressPath, + }, + ], + changeAmount: 4n, }); const getInputDataMock = (xp: string, dtsh: Buffer) => Buffer.alloc(0); @@ -1768,6 +2515,158 @@ test('createTokens', async () => { spy4.mockRestore(); }); +test('prepareCreateNewToken - fee token with mint authority and change outputs', async () => { + const addresses = [ + 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', + 'WbjNdAGBWAkCS2QVpqmacKXNy8WVXatXNM', + 'WR1i8USJWQuaU423fwuFQbezfevmT4vFWX', + ]; + + const requestPassword = jest.fn(); + const network = new Network('testnet'); + const seed = + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff'; + const wallet = new HathorWalletServiceWallet({ + requestPassword, + seed, + network, + passphrase: '', + xpriv: null, + xpub: null, + }); + wallet.setState('Ready'); + + const _spyGetUtxos = jest.spyOn(wallet, 'getUtxos').mockImplementation(async () => ({ + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: '00', + address: addresses[0], + value: 10n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 9n, + })); + + const _spyGetUtxosForAmount = jest + .spyOn(wallet, 'getUtxosForAmount') + .mockImplementation(async amount => ({ + utxos: [ + { + txId: '002abde4018935e1bbde9600ef79c637adf42385fb1816ec284d702b7bb9ef5d', + index: 0, + tokenId: '00', + address: addresses[0], + value: 10n, + authorities: 0n, + timelock: null, + heightlock: null, + locked: false, + addressPath: "m/280'/280'/0/1/0", + }, + ], + changeAmount: 9n, + })); + + const code = new Mnemonic( + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff' + ); + const xpriv = code.toHDPrivateKey('', network.getNetwork()); + + jest.spyOn(wallet.storage, 'getMainXPrivKey').mockReturnValue(Promise.resolve(xpriv.xprivkey)); + jest.spyOn(wallet, 'getInputData').mockImplementation(() => Buffer.alloc(0)); + jest.spyOn(wallet, 'getCurrentAddress').mockImplementation(() => ({ + address: addresses[0], + index: 0, + addressPath: "m/280'/280'/0/1/0", + })); + + const result = await wallet.prepareCreateNewToken('Test Token', 'TSTF', 1000n, { + address: addresses[1], + createMintAuthority: true, + mintAuthorityAddress: addresses[2], + pinCode: '123456', + tokenVersion: TokenVersion.FEE, + }); + + expect(result.inputs).toEqual([expect.objectContaining({ data: expect.any(Object) })]); + expect(result.outputs).toHaveLength(4); + + const authorityOutputs = result.outputs.filter(o => + transaction.isAuthorityOutput({ token_data: o.tokenData }) + ); + expect(authorityOutputs).toHaveLength(2); + + const mintAuth = authorityOutputs.find(o => o.value === TOKEN_MINT_MASK); + expect(mintAuth).toBeDefined(); + const p2pkh = mintAuth?.parseScript(network); + expect(p2pkh?.address?.base58).toBe(addresses[2]); + + _spyGetUtxos.mockRestore(); + _spyGetUtxosForAmount.mockRestore(); +}); + +test('prepareCreateNewToken - fee token without enough HTR for fee', async () => { + const addresses = [ + 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', + 'WbjNdAGBWAkCS2QVpqmacKXNy8WVXatXNM', + 'WR1i8USJWQuaU423fwuFQbezfevmT4vFWX', + ]; + + const requestPassword = jest.fn(); + const network = new Network('testnet'); + const seed = + 'purse orchard camera cloud piece joke hospital mechanic timber horror shoulder rebuild you decrease garlic derive rebuild random naive elbow depart okay parrot cliff'; + const wallet = new HathorWalletServiceWallet({ + requestPassword, + seed, + network, + passphrase: '', + xpriv: null, + xpub: null, + }); + wallet.setState('Ready'); + + jest.spyOn(wallet, 'getCurrentAddress').mockImplementation(() => ({ + address: addresses[0], + index: 0, + addressPath: "m/280'/280'/0/1/0", + })); + + const _spyGetUtxos = jest.spyOn(wallet, 'getUtxos').mockImplementation(async () => ({ + utxos: [], + changeAmount: 0n, + })); + + const _spyGetUtxosForAmount = jest + .spyOn(wallet, 'getUtxosForAmount') + .mockImplementation(async () => ({ + utxos: [], + changeAmount: 0n, + })); + + jest.spyOn(Fee, 'calculateTokenCreationTxFee').mockReturnValue(1000n); + + await expect( + wallet.prepareCreateNewToken('Test Token', 'TSTF', 1000n, { + address: addresses[1], + createMintAuthority: true, + mintAuthorityAddress: addresses[2], + pinCode: '123456', + tokenVersion: TokenVersion.FEE, + }) + ).rejects.toThrow('No utxos available to fill the request. Token: HTR - Amount: 1000.'); + + _spyGetUtxos.mockRestore(); + _spyGetUtxosForAmount.mockRestore(); +}); + test('createNFTs', async () => { const addresses = [ 'WdSD7aytFEZ5Hp8quhqu3wUCsyyGqcneMu', diff --git a/__tests__/wallet/walletSchemas.test.ts b/__tests__/wallet/walletSchemas.test.ts index 3676c058d..514cc8470 100644 --- a/__tests__/wallet/walletSchemas.test.ts +++ b/__tests__/wallet/walletSchemas.test.ts @@ -166,6 +166,7 @@ describe('Wallet API Schemas', () => { id: token1, name: 'Token 1', symbol: 'T1', + version: 1, // TokenVersion.DEPOSIT }, totalSupply: '1000', totalTransactions: 5, @@ -209,6 +210,7 @@ describe('Wallet API Schemas', () => { id: token1, name: 'Token 1', symbol: 'T1', + version: 1, // TokenVersion.DEPOSIT }, balance: { unlocked: '100', diff --git a/src/api/schemas/wallet.ts b/src/api/schemas/wallet.ts index 9961fc70e..cb69cfcf7 100644 --- a/src/api/schemas/wallet.ts +++ b/src/api/schemas/wallet.ts @@ -37,6 +37,7 @@ export const generalTokenInfoSchema = z.discriminatedUnion('success', [ success: z.literal(true), name: z.string(), symbol: z.string(), + version: z.number().optional().nullable(), mint: mintMeltUtxoSchema.array(), melt: mintMeltUtxoSchema.array(), total: bigIntCoercibleSchema, diff --git a/src/constants.ts b/src/constants.ts index bcfa0926b..501af0eac 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import { AddressScanPolicy, OutputValueType, SCANNING_POLICY } from './types'; +import { AddressScanPolicy, OutputValueType, SCANNING_POLICY, TokenVersion } from './types'; /** * Constants defined for the Hathor Wallet @@ -96,12 +96,6 @@ export const NANO_CONTRACTS_INITIALIZE_METHOD = 'initialize'; */ export const ON_CHAIN_BLUEPRINTS_INFO_VERSION = 1; -/** - * Create token information version - * so far we expect name and symbol - */ -export const TOKEN_INFO_VERSION = 1; - /** * Max value (inclusive) before having to use 8 bytes: 2147483648 ~= 2.14748e+09 */ @@ -157,6 +151,7 @@ export const NATIVE_TOKEN_UID: string = '00'; export const DEFAULT_NATIVE_TOKEN_CONFIG = { name: 'Hathor', symbol: 'HTR', + version: TokenVersion.NATIVE, }; /** @@ -295,6 +290,11 @@ export const HATHOR_MAGIC_BYTES = 'Hathor Signed Message:\n'; */ export const DEFAULT_ADDRESS_SCANNING_POLICY: AddressScanPolicy = SCANNING_POLICY.GAP_LIMIT; +/** + * Fee per output + */ +export const FEE_PER_OUTPUT: bigint = 1n; + /** * Max argument length in bytes (64Kib) */ diff --git a/src/errors.ts b/src/errors.ts index 3d4de7af3..5d95db113 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -63,6 +63,18 @@ export class CreateTokenTxInvalid extends Error {} */ export class TokenValidationError extends Error {} +/** + * Error thrown when a token is not found + * + * @memberof Errors + * @inner + */ +export class TokenNotFoundError extends Error { + constructor(token: string) { + super(`Token ${token} not found in tokens.`); + } +} + /** * Error thrown when validating a registration of new NFT * @@ -195,7 +207,7 @@ export class UtxoError extends WalletError {} export class SendTxError extends WalletError { // XXX: There are only two out of dozens of places where this object is used instead of a string. // This should be made consistently for strings - errorData: string | { txId: string; index: number } = ''; + errorData: string | { txId: string; index: number } | { txId: string; index: number }[] = ''; } /** diff --git a/src/headers/fee.ts b/src/headers/fee.ts index a4b4bc067..89e93aac0 100644 --- a/src/headers/fee.ts +++ b/src/headers/fee.ts @@ -49,6 +49,8 @@ class FeeHeader extends Header { * @inner */ serializeFields(array: Buffer[]) { + array.push(getVertexHeaderIdBuffer(VertexHeaderId.FEE_HEADER)); + // Number of entries array.push(intToBytes(this.entries.length, 1)); @@ -80,9 +82,6 @@ class FeeHeader extends Header { * @inner */ serialize(array: Buffer[]) { - // First add the header ID - array.push(getVertexHeaderIdBuffer(VertexHeaderId.FEE_HEADER)); - // Then the serialized fields this.serializeFields(array); } diff --git a/src/headers/index.ts b/src/headers/index.ts new file mode 100644 index 000000000..6b62c966a --- /dev/null +++ b/src/headers/index.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) Hathor Labs and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export { default as Header } from './base'; +export { default as FeeHeader } from './fee'; +export * from './parser'; +export * from './types'; diff --git a/src/lib.ts b/src/lib.ts index 00ee1d62c..bd8f50c53 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -58,6 +58,9 @@ import { WalletTxTemplateInterpreter, } from './template/transaction'; import { stopGLLBackgroundTask } from './sync/gll'; +import * as enums from './models/enum'; +import type { TokenInfo } from './wallet/types'; +import { Fee } from './utils/fee'; export { PartialTx, @@ -95,6 +98,7 @@ export { CreateTokenTransaction, Network, FeeHeader, + Fee, addressUtils, cryptoUtils, dateFormatter as dateUtils, @@ -121,9 +125,12 @@ export { TransactionTemplateBuilder, WalletTxTemplateInterpreter, stopGLLBackgroundTask, + TokenInfo, + enums, }; export * from './nano_contracts/types'; export * from './models/types'; export type { IHathorWallet, OutputRequestObj, DataScriptOutputRequestObj } from './wallet/types'; export type { IFeeEntry } from './types'; +export * from './models/enum'; diff --git a/src/models/create_token_transaction.ts b/src/models/create_token_transaction.ts index 02919fec4..365cca572 100644 --- a/src/models/create_token_transaction.ts +++ b/src/models/create_token_transaction.ts @@ -9,7 +9,6 @@ import buffer from 'buffer'; import { clone } from 'lodash'; import { CREATE_TOKEN_TX_VERSION, - TOKEN_INFO_VERSION, MAX_TOKEN_NAME_SIZE, MAX_TOKEN_SYMBOL_SIZE, DEFAULT_SIGNAL_BITS, @@ -22,6 +21,7 @@ import Network from './network'; import { CreateTokenTxInvalid, InvalidOutputsError, NftValidationError } from '../errors'; import ScriptData from './script_data'; import { OutputType } from '../wallet/types'; +import { TokenVersion } from '../types'; import type Header from '../headers/base'; type optionsType = { @@ -32,6 +32,7 @@ type optionsType = { parents?: string[]; tokens?: string[]; hash?: string | null; + tokenVersion?: TokenVersion; headers?: Header[]; }; @@ -40,6 +41,8 @@ class CreateTokenTransaction extends Transaction { symbol: string; + tokenVersion: TokenVersion; + constructor( name: string, symbol: string, @@ -55,6 +58,7 @@ class CreateTokenTransaction extends Transaction { parents: [], tokens: [], hash: null, + tokenVersion: TokenVersion.DEPOSIT, headers: [], }; const newOptions = Object.assign(defaultOptions, options); @@ -63,6 +67,7 @@ class CreateTokenTransaction extends Transaction { this.version = CREATE_TOKEN_TX_VERSION; this.name = name; this.symbol = symbol; + this.tokenVersion = newOptions.tokenVersion ?? TokenVersion.DEPOSIT; } /** @@ -98,6 +103,10 @@ class CreateTokenTransaction extends Transaction { * @inner */ serializeTokenInfo(array: Buffer[]) { + if (!this.tokenVersion) { + throw new CreateTokenTxInvalid('Token version is required when creating a new token'); + } + if (!this.name || !this.symbol) { throw new CreateTokenTxInvalid( 'Token name and symbol are required when creating a new token' @@ -118,8 +127,9 @@ class CreateTokenTransaction extends Transaction { const nameBytes = buffer.Buffer.from(this.name, 'utf8'); const symbolBytes = buffer.Buffer.from(this.symbol, 'utf8'); + // Token info version - array.push(intToBytes(TOKEN_INFO_VERSION, 1)); + array.push(intToBytes(this.tokenVersion, 1)); // Token name size array.push(intToBytes(nameBytes.length, 1)); // Token name @@ -131,7 +141,7 @@ class CreateTokenTransaction extends Transaction { } getTokenInfoFromBytes(srcBuf: Buffer): Buffer { - let tokenInfoVersion; + let tokenVersion; let lenName; let lenSymbol; let bufName; @@ -140,10 +150,12 @@ class CreateTokenTransaction extends Transaction { let buf = Buffer.from(srcBuf); /* eslint-disable prefer-const -- To split these declarations into const + let would be confusing */ - [tokenInfoVersion, buf] = unpackToInt(1, false, buf); + [tokenVersion, buf] = unpackToInt(1, false, buf); + this.tokenVersion = tokenVersion; - if (tokenInfoVersion !== TOKEN_INFO_VERSION) { - throw new CreateTokenTxInvalid(`Unknown token info version: ${tokenInfoVersion}`); + const allowedVersions = new Set([TokenVersion.DEPOSIT, TokenVersion.FEE]); + if (!allowedVersions.has(tokenVersion)) { + throw new CreateTokenTxInvalid(`Unknown token info version: ${tokenVersion}`); } [lenName, buf] = unpackToInt(1, false, buf); @@ -233,7 +245,7 @@ class CreateTokenTransaction extends Transaction { * @inner */ static createFromBytes(buf: Buffer, network: Network): CreateTokenTransaction { - const tx = new CreateTokenTransaction('', '', [], []); + const tx = CreateTokenTransaction.createEmpty(); // Cloning buffer so we don't mutate anything sent by the user // as soon as it's available natively we should use an immutable buffer @@ -311,6 +323,17 @@ class CreateTokenTransaction extends Transaction { throw new NftValidationError('A maximum of 1 of each mint and melt is allowed'); } } + + /** + * Create an empty transaction + * @return {CreateTokenTransaction} Transaction object + * @memberof CreateTokenTransaction + * @static + * @inner + */ + static createEmpty(): CreateTokenTransaction { + return new CreateTokenTransaction('', '', [], []); + } } export default CreateTokenTransaction; diff --git a/src/models/enum/index.ts b/src/models/enum/index.ts new file mode 100644 index 000000000..511670162 --- /dev/null +++ b/src/models/enum/index.ts @@ -0,0 +1 @@ +export { TokenVersion } from '../../types'; diff --git a/src/models/types.ts b/src/models/types.ts index 4267316fa..91c262b78 100644 --- a/src/models/types.ts +++ b/src/models/types.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import { OutputValueType } from '../types'; +import { OutputValueType, TokenVersion } from '../types'; /** * An output object enriched by the wallet's history methods @@ -58,6 +58,7 @@ export type HistoryTransaction = { parents: string[]; token_name?: string; token_symbol?: string; + token_version?: TokenVersion; tokens: string[]; }; diff --git a/src/nano_contracts/utils.ts b/src/nano_contracts/utils.ts index 35d82855b..9c08c34a4 100644 --- a/src/nano_contracts/utils.ts +++ b/src/nano_contracts/utils.ts @@ -271,11 +271,9 @@ export const mapActionToActionHeader = ( ): NanoContractActionHeader => { const headerActionType = ActionTypeToActionHeaderType[action.type]; - const mappedTokens: ITokenData[] = tokens.map(token => { + const mappedTokens: Partial[] = tokens.map(token => { return { uid: token, - name: '', - symbol: '', }; }); diff --git a/src/new/sendTransaction.ts b/src/new/sendTransaction.ts index bf9330fc0..f24779c18 100644 --- a/src/new/sendTransaction.ts +++ b/src/new/sendTransaction.ts @@ -7,30 +7,35 @@ import EventEmitter from 'events'; import { shuffle } from 'lodash'; -import { SELECT_OUTPUTS_TIMEOUT, NATIVE_TOKEN_UID } from '../constants'; -import transactionUtils from '../utils/transaction'; import txApi from '../api/txApi'; -import { WalletError, SendTxError } from '../errors'; +import { NATIVE_TOKEN_UID, SELECT_OUTPUTS_TIMEOUT } from '../constants'; import { ErrorMessages } from '../errorMessages'; -import helpers from '../utils/helpers'; -import MineTransaction from '../wallet/mineTransaction'; +import { SendTxError, WalletError } from '../errors'; import Address from '../models/address'; -import { OutputType } from '../wallet/types'; +import CreateTokenTransaction from '../models/create_token_transaction'; +import { Fee } from '../utils/fee'; +import Transaction from '../models/transaction'; import { - IStorage, - IDataTx, - IDataOutput, IDataInput, - IUtxoSelectionOptions, + IDataOutput, + IDataOutputWithToken, + IDataTx, isDataOutputCreateToken, - WalletType, + IStorage, + IUtxoSelectionOptions, OutputValueType, + WalletType, } from '../types'; -import Transaction from '../models/transaction'; -import { bestUtxoSelection } from '../utils/utxo'; +import helpers from '../utils/helpers'; import { addCreatedTokenFromTx } from '../utils/storage'; -import CreateTokenTransaction from '../models/create_token_transaction'; +import tokens from '../utils/tokens'; +import transactionUtils from '../utils/transaction'; +import { bestUtxoSelection } from '../utils/utxo'; +import MineTransaction from '../wallet/mineTransaction'; +import { OutputType } from '../wallet/types'; import HathorWallet from './wallet'; +import Header from '../headers/base'; +import FeeHeader from '../headers/fee'; export interface ISendInput { txId: string; @@ -193,6 +198,8 @@ export default class SendTransaction extends EventEmitter { } } + const requiresFees: { txId: string; index: number }[] = []; + for (const input of this.inputs) { const inputTx = await this.storage.getTx(input.txId); if (inputTx === null || !inputTx.outputs[input.index]) { @@ -202,10 +209,15 @@ export default class SendTransaction extends EventEmitter { } const spentOut = inputTx.outputs[input.index]; if (!tokenMap.has(spentOut.token)) { - // The input select is from a token that is not in the outputs - const err = new SendTxError(ErrorMessages.INVALID_INPUT); - err.errorData = { txId: input.txId, index: input.index }; - throw err; + // the inputs should be used to pay fees, otherwise it's an invalid input and it will raise an error after the fee is calculated + if (HTR_UID === spentOut.token) { + requiresFees.push({ txId: input.txId, index: input.index }); + } else { + // The input select is from a token that is not in the outputs + const err = new SendTxError(ErrorMessages.INVALID_INPUT); + err.errorData = { txId: input.txId, index: input.index }; + throw err; + } } tokenMap.set(spentOut.token, false); txData.inputs.push({ @@ -218,41 +230,84 @@ export default class SendTransaction extends EventEmitter { }); } - const partialTxData: Pick = { inputs: [], outputs: [] }; - for (const [token, chooseInputs] of tokenMap) { - const options: IUtxoSelectionOptions = { - token, - chooseInputs, - }; - if (this.changeAddress) { - options.changeAddress = this.changeAddress; - } - try { - const proposedData = await prepareSendTokensData(this.storage, txData, options); - partialTxData.inputs.push(...proposedData.inputs); - partialTxData.outputs.push(...proposedData.outputs); - } catch (e) { - if (e instanceof Error) { - throw new SendTxError(e.message); - } - throw e; + // If the user provided HTR inputs, tokenMap.get(HTR_UID) will be false + // In that case, we should NOT choose inputs automatically (accept what user provided) + // Otherwise (true or undefined), we should choose HTR inputs if needed for fee + const tokenMapHasHTR = tokenMap.has(HTR_UID); + let shouldChooseHTRInputs = tokenMap.get(HTR_UID) || false; + + // we remove HTR from the tokenMap since we will calculate the fee based on the inputs and outputs + // and we don't want to select inputs for HTR before that + tokenMap.delete(HTR_UID); + + const partialTxData = await prepareSendManyTokensData( + this.storage, + txData, + tokenMap, + this.changeAddress + ); + + const partialInputs = [...txData.inputs, ...partialTxData.inputs]; + const partialOutputs = [...txData.outputs, ...partialTxData.outputs] as IDataOutputWithToken[]; + + // calculate the fee based in the inputs and outputs, including the change output + // fee is always in HTR + const fee = await Fee.calculate( + partialInputs, + partialOutputs, + await tokens.getTokensByManyIds(this.storage, new Set(tokenMap.keys())) + ); + + if (requiresFees.length > 0 && fee === 0n) { + const err = new SendTxError(ErrorMessages.INVALID_INPUT); + err.errorData = requiresFees; + throw err; + } + + const headers: Header[] = []; + if (fee > 0) { + headers.push(new FeeHeader([{ tokenIndex: 0, amount: fee }])); + // if the token map doesn't have HTR, it means that the user didn't provide any HTR input or output, so we need to choose inputs for HTR to pay fees + if (!tokenMapHasHTR) { + shouldChooseHTRInputs = true; } } - let outputs: IDataOutput[]; - if (partialTxData.outputs.length === 0) { - outputs = txData.outputs; - } else { + const options: IUtxoSelectionOptions = { + token: HTR_UID, + chooseInputs: shouldChooseHTRInputs, + }; + + if (this.changeAddress) { + options.changeAddress = this.changeAddress; + } + + const partialHtrTxData = await prepareSendTokensData( + this.storage, + { + inputs: partialInputs, + outputs: partialOutputs, + }, + options, + fee + ); + + const shouldShuffleOutputs = + partialTxData.outputs.length > 0 || partialHtrTxData.outputs.length > 0; + // we initialize the outputs with the provided outputs to keep the order + let outputs = [...txData.outputs]; + if (shouldShuffleOutputs) { // Shuffle outputs, so we don't have change output always in the same index - outputs = shuffle([...txData.outputs, ...partialTxData.outputs]); + outputs = shuffle([...partialOutputs, ...partialHtrTxData.outputs]); } - tokenMap.delete(HTR_UID); // This new IDataTx should be complete with the requested funds this.fullTxData = { outputs, - inputs: [...txData.inputs, ...partialTxData.inputs], + inputs: [...partialInputs, ...partialHtrTxData.inputs], + // We already removed HTR from the tokenMap tokens: Array.from(tokenMap.keys()), + headers, }; return this.fullTxData; @@ -582,29 +637,46 @@ export default class SendTransaction extends EventEmitter { * We will only check a single token * * @param {IStorage} storage - * @param {IDataTx} dataTx + * @param {Pick} dataTx inputs and outputs from dataTx * @param {IUtxoSelectionOptions} options */ export async function prepareSendTokensData( storage: IStorage, - dataTx: IDataTx, - options: IUtxoSelectionOptions = {} + dataTx: Pick, + options: IUtxoSelectionOptions = {}, + fee: bigint = 0n ): Promise> { - async function getOutputTypeFromWallet(): Promise<'p2pkh' | 'p2sh'> { - const walletType = await storage.getWalletType(); - if (walletType === WalletType.P2PKH) { - return 'p2pkh'; - } - if (walletType === WalletType.MULTISIG) { - return 'p2sh'; + try { + return await _prepareSendTokensData(storage, dataTx, options, fee); + } catch (e) { + if (e instanceof Error) { + throw new SendTxError(e.message); } - throw new Error('Unsupported wallet type.'); + throw e; + } +} + +async function getOutputTypeFromWallet(storage: IStorage): Promise<'p2pkh' | 'p2sh'> { + const walletType = await storage.getWalletType(); + if (walletType === WalletType.P2PKH) { + return 'p2pkh'; + } + if (walletType === WalletType.MULTISIG) { + return 'p2sh'; } + throw new Error('Unsupported wallet type.'); +} +async function _prepareSendTokensData( + storage: IStorage, + dataTx: Pick, + options: IUtxoSelectionOptions = {}, + fee: bigint = 0n +): Promise> { const token = options.token || NATIVE_TOKEN_UID; const utxoSelection = options.utxoSelectionMethod || bestUtxoSelection; const newtxData: Pick = { inputs: [], outputs: [] }; - let outputAmount = 0n; + let outputAmount = fee; // Calculate balance for the token on the transaction for (const output of dataTx.outputs) { @@ -640,7 +712,7 @@ export async function prepareSendTokensData( changeAddress: options.changeAddress, }); const changeOutput: IDataOutput = { - type: await getOutputTypeFromWallet(), + type: await getOutputTypeFromWallet(storage), token, value: newUtxos.amount - outputAmount, address: changeAddress, @@ -683,7 +755,7 @@ export async function prepareSendTokensData( changeAddress: options.changeAddress, }); newtxData.outputs.push({ - type: await getOutputTypeFromWallet(), + type: await getOutputTypeFromWallet(storage), token, value: inputAmount - outputAmount, address: changeAddress, @@ -693,10 +765,38 @@ export async function prepareSendTokensData( }); } } - return newtxData; } +/** + * Check the tx data and propose inputs and outputs to complete the transaction. + * We will check all the tokens and choose the inputs for each token based on the tokenMap value + * @param {IStorage} storage + * @param {IDataTx} dataTx + * @param {IUtxoSelectionOptions} options + */ +export async function prepareSendManyTokensData( + storage: IStorage, + txData: IDataTx, + tokenMap: Map, + changeAddress: string | null +): Promise> { + const partialTxData: Pick = { inputs: [], outputs: [] }; + for (const [token, chooseInputs] of tokenMap) { + const options: IUtxoSelectionOptions = { + token, + chooseInputs, + }; + if (changeAddress) { + options.changeAddress = changeAddress; + } + const proposedData = await prepareSendTokensData(storage, txData, options); + partialTxData.inputs.push(...proposedData.inputs); + partialTxData.outputs.push(...proposedData.outputs); + } + return partialTxData; +} + /** * Check that the input is unspent, valid and available. * Will return a user-friendly message if it is not. diff --git a/src/new/wallet.ts b/src/new/wallet.ts index 5ca8ae6f5..762bb9f74 100644 --- a/src/new/wallet.ts +++ b/src/new/wallet.ts @@ -60,6 +60,7 @@ import { HistorySyncMode, getDefaultLogger, } from '../types'; +import { TokenVersion } from '../models/enum'; import transactionUtils from '../utils/transaction'; import Queue from '../models/queue'; import { @@ -84,6 +85,7 @@ import Address from '../models/address'; /** * @typedef {import('../models/create_token_transaction').default} CreateTokenTransaction * @typedef {import('../models/transaction').default} Transaction + * @typedef {import('../types').TokenVersion} TokenVersion */ const ERROR_MESSAGE_PIN_REQUIRED = 'Pin is required.'; @@ -735,7 +737,7 @@ class HathorWallet extends EventEmitter { * @param {string|null|undefined} token * * @return {Promise<{ - * token: {id:string, name:string, symbol:string}, + * token: {id:string, name:string, symbol:string, version: TokenVersion}, * balance: {unlocked:bigint, locked:bigint}, * transactions:number, * lockExpires:number|null, @@ -775,6 +777,7 @@ class HathorWallet extends EventEmitter { id: tokenData.uid, name: tokenData.name, symbol: tokenData.symbol, + version: tokenData.version, }, balance: tokenData.balance.tokens, transactions: tokenData.numTransactions, @@ -1732,6 +1735,7 @@ class HathorWallet extends EventEmitter { * @property {string[]?} [data=null] list of data strings using utf8 encoding to add each as a data script output * @property {boolean?} [signTx=true] sign transaction instance * @property {boolean?} [isCreateNFT=false] if the create token is an NFT creation call + * @property {TokenVersion?} [tokenVersion=TokenVersion.DEPOSIT] version of the token to be created */ /** @@ -1771,6 +1775,7 @@ class HathorWallet extends EventEmitter { data: null, isCreateNFT: false, signTx: true, + tokenVersion: TokenVersion.DEPOSIT, ...options, }; @@ -1811,6 +1816,7 @@ class HathorWallet extends EventEmitter { meltAuthorityAddress: newOptions.meltAuthorityAddress, data: newOptions.data, isCreateNFT: newOptions.isCreateNFT, + tokenVersion: newOptions.tokenVersion, } ); return transactionUtils.prepareTransaction(txData, pin, this.storage, { @@ -2471,6 +2477,7 @@ class HathorWallet extends EventEmitter { uid: this.tokenUid, name: response.name, symbol: response.symbol, + version: response.version, }; } else { throw Error(response.message); @@ -2490,6 +2497,7 @@ class HathorWallet extends EventEmitter { * tokenInfo: { * name: string, * symbol: string, + * version: TokenVersion, * }, * authorities: { * mint: boolean, @@ -2507,7 +2515,7 @@ class HathorWallet extends EventEmitter { throw new Error(result.message); } - const { name, symbol, mint, melt, total, transactions_count }: any = result; + const { name, symbol, mint, melt, total, transactions_count, version } = result; // Transform to the same format the wallet service facade responds return { @@ -2517,6 +2525,7 @@ class HathorWallet extends EventEmitter { id: tokenId, name, symbol, + version, }, authorities: { mint: mint.length > 0, @@ -2883,6 +2892,7 @@ class HathorWallet extends EventEmitter { * version: number, * voided: boolean, * weight: number, + * tokenId: string, * tokenName: string, * tokenSymbol: string, * balance: bigint diff --git a/src/storage/memory_store.ts b/src/storage/memory_store.ts index 8cbb81fe4..6bb496a17 100644 --- a/src/storage/memory_store.ts +++ b/src/storage/memory_store.ts @@ -24,6 +24,7 @@ import { IIndexLimitAddressScanPolicy, SCANNING_POLICY, INcData, + TokenVersion, } from '../types'; import { GAP_LIMIT, NATIVE_TOKEN_UID } from '../constants'; import transactionUtils from '../utils/transaction'; @@ -546,9 +547,10 @@ export class MemoryStore implements IStore { if (this.tokens.has(tokenConfig.uid)) { throw new Error('Already have this token'); } - this.tokens.set(tokenConfig.uid, tokenConfig); + const newTokenConfig = { version: TokenVersion.DEPOSIT, ...tokenConfig }; // Clone the token config to avoid modifying the original object + this.tokens.set(newTokenConfig.uid, newTokenConfig); if (meta !== undefined) { - this.tokensMetadata.set(tokenConfig.uid, meta); + this.tokensMetadata.set(newTokenConfig.uid, meta); } } diff --git a/src/template/transaction/context.ts b/src/template/transaction/context.ts index bdd91adea..31445b663 100644 --- a/src/template/transaction/context.ts +++ b/src/template/transaction/context.ts @@ -7,7 +7,7 @@ /* eslint max-classes-per-file: ["error", 3] */ import { z } from 'zod'; -import { IHistoryTx, ILogger, OutputValueType, getDefaultLogger } from '../../types'; +import { TokenVersion, IHistoryTx, ILogger, OutputValueType, getDefaultLogger } from '../../types'; import Input from '../../models/input'; import Output from '../../models/output'; import transactionUtils from '../../utils/transaction'; @@ -192,6 +192,8 @@ export class TxTemplateContext { nanoContext?: NanoContractContext; + tokenVersion?: TokenVersion; + vars: Record; _logs: string[]; diff --git a/src/template/transaction/executor.ts b/src/template/transaction/executor.ts index 185ed50ac..6af7908ca 100644 --- a/src/template/transaction/executor.ts +++ b/src/template/transaction/executor.ts @@ -7,7 +7,6 @@ import { z } from 'zod'; import { clone, shuffle } from 'lodash'; -import { OutputValueType } from 'src/types'; import { AuthorityOutputInstruction, AuthoritySelectInstruction, @@ -53,6 +52,7 @@ import { getWalletBalance, } from './setvarcommands'; import { selectAuthorities, selectTokens } from './utils'; +import { TokenVersion, OutputValueType } from '../../types'; /** * Find and run the executor function for the instruction. @@ -680,13 +680,18 @@ export async function execConfigInstruction( ctx.vars, ConfigInstruction.shape.tokenSymbol ); + const tokenVersion = getVariable( + ins.tokenVersion, + ctx.vars, + ConfigInstruction.shape.tokenVersion + ); const createToken = getVariable( ins.createToken, ctx.vars, ConfigInstruction.shape.createToken ); ctx.log( - `version(${version}) signalBits(${signalBits}) tokenName(${tokenName}) tokenSymbol(${tokenSymbol}) createToken(${createToken})` + `version(${version}) signalBits(${signalBits}) tokenName(${tokenName}) tokenSymbol(${tokenSymbol}) tokenVersion(${tokenVersion}) createToken(${createToken})` ); if (version) { @@ -701,6 +706,9 @@ export async function execConfigInstruction( if (tokenSymbol) { ctx.tokenSymbol = tokenSymbol; } + if (tokenVersion) { + ctx.tokenVersion = tokenVersion; + } if (createToken) { ctx.useCreateTokenTxContext(); } diff --git a/src/template/transaction/instructions.ts b/src/template/transaction/instructions.ts index a43e67bc4..677d9b115 100644 --- a/src/template/transaction/instructions.ts +++ b/src/template/transaction/instructions.ts @@ -7,6 +7,7 @@ import { z } from 'zod'; import { NATIVE_TOKEN_UID } from '../../constants'; +import { TokenVersion } from '../../types'; const TEMPLATE_REFERENCE_NAME_RE = /[\w\d]+/; const TEMPLATE_REFERENCE_RE = /\{([\w\d]+)\}/; @@ -182,6 +183,7 @@ export const ConfigInstruction = z.object({ createToken: TemplateRef.or(z.boolean().optional()), tokenName: TemplateRef.or(z.string().min(1).max(30).optional()), tokenSymbol: TemplateRef.or(z.string().min(1).max(5).optional()), + tokenVersion: TemplateRef.or(z.nativeEnum(TokenVersion).default(TokenVersion.DEPOSIT)), }); export const SetVarGetWalletAddressOpts = z.object({ diff --git a/src/template/transaction/interpreter.ts b/src/template/transaction/interpreter.ts index 69441ca1e..b05a276f7 100644 --- a/src/template/transaction/interpreter.ts +++ b/src/template/transaction/interpreter.ts @@ -181,12 +181,15 @@ export class WalletTxTemplateInterpreter implements ITxTemplateInterpreter { if (!context.tokenName || !context.tokenSymbol) { throw new Error('Cannot create a token without a name or symbol'); } + if (!context.tokenVersion) { + throw new Error('Cannot create a token without a token version'); + } return new CreateTokenTransaction( context.tokenName, context.tokenSymbol, context.inputs, context.outputs, - { signalBits: context.signalBits, headers } + { signalBits: context.signalBits, headers, tokenVersion: context.tokenVersion } ); } throw new Error('Unsupported Version byte provided'); diff --git a/src/types.ts b/src/types.ts index 7deffbedb..5661d31e9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,6 +9,18 @@ import { Config } from './config'; import Transaction from './models/transaction'; import Input from './models/input'; import FullNodeConnection from './new/connection'; +import Header from './headers/base'; + +/** + * Token version used to identify the type of token during the token creation process. + */ +export enum TokenVersion { + NATIVE = 0, + + DEPOSIT = 1, + + FEE = 2, +} /** * Logger interface where each method is a leveled log method. @@ -86,6 +98,7 @@ export interface ITokenData { uid: string; name: string; symbol: string; + version?: TokenVersion; } export interface ITokenMetadata { @@ -179,6 +192,7 @@ export interface IHistoryTx { parents: string[]; token_name?: string; // For create token transaction token_symbol?: string; // For create token transaction + token_version?: TokenVersion; // For create token transaction tokens?: string[]; height?: number; processingStatus?: TxHistoryProcessingStatus; @@ -271,6 +285,8 @@ export interface IDataOutputOptionals { export type IDataOutput = (IDataOutputData | IDataOutputAddress | IDataOutputCreateToken) & IDataOutputOptionals; +export type IDataOutputWithToken = IDataOutput & { token: string }; + export interface IDataInput { txId: string; index: number; @@ -281,9 +297,15 @@ export interface IDataInput { data?: string; } +interface IDataTokenCreationTx { + name: string; + symbol: string; + tokenVersion: TokenVersion; // `tokenVersion` cannot be named `version` because it conflicts with the `version` property of the `IDataTx` interface +} + // XXX: This type is meant to be used as an intermediary for building transactions // It should have everything we need to build and push transactions. -export interface IDataTx { +export interface IDataTx extends Partial { signalBits?: number; version?: number; inputs: IDataInput[]; @@ -293,8 +315,7 @@ export interface IDataTx { nonce?: number; timestamp?: number; parents?: string[]; - name?: string; // For create token transaction - symbol?: string; // For create token transaction + headers?: Header[]; } export interface IUtxoId { diff --git a/src/utils/fee.ts b/src/utils/fee.ts new file mode 100644 index 000000000..d523b8d4e --- /dev/null +++ b/src/utils/fee.ts @@ -0,0 +1,131 @@ +/** + * Copyright (c) Hathor Labs and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { TokenInfo, Utxo } from '../wallet/types'; +import { FEE_PER_OUTPUT, NATIVE_TOKEN_UID } from '../constants'; +import { IDataInput, IDataOutputWithToken, ITokenData, IUtxo, TokenVersion } from '../types'; +import Output from '../models/output'; + +type TokenElement = IDataInput | Utxo | IUtxo | IDataInput | IDataOutputWithToken | Output; + +export class Fee { + /** + * Calculate the fee for a transaction. + * + * https://github.com/HathorNetwork/rfcs/pull/94 + * According to the fee rfc, the fee is calculated based on the number of non-authority outputs. + * If the transaction is a create token transaction, the fee is calculated based on the number of outputs related to the token being created. + * If the transaction is a melt operation, the fee is calculated based on the number of outputs related to the token being melted. In this case, we should consider the melt operation without outputs as a non-authority output. + * + * @param inputs the inputs of the transaction + * @param outputs the outputs of the transaction + * @param tokens the map with token data + * @returns fee amount in HTR + */ + static async calculate( + inputs: (IDataInput | Utxo | IUtxo)[], + outputs: (IDataOutputWithToken | Output)[], + tokens: Map + ): Promise { + const nonAuthorityInputs = Fee.groupTokenElementsByTokenUid(inputs); + const nonAuthorityOutputs = Fee.groupTokenElementsByTokenUid(outputs); + + const tokensSet = new Set([...nonAuthorityInputs.keys(), ...nonAuthorityOutputs.keys()]); + tokensSet.delete(NATIVE_TOKEN_UID); + + let fee = 0n; + + for (const token of tokensSet) { + const tokenData = tokens.get(token); + if (!tokenData) { + throw new Error(`Token ${token} not found in tokens.`); + } + + if (tokenData.version !== TokenVersion.FEE) { + continue; + } + // melt operation without outputs should be charged + if (nonAuthorityInputs.has(token) && !nonAuthorityOutputs.has(token)) { + fee += FEE_PER_OUTPUT; + } + + fee += BigInt((nonAuthorityOutputs.get(token) || []).length) * FEE_PER_OUTPUT; + } + + return fee; + } + + /** + * Simplified fee calculation for a create token transaction with outputs related to the token being created. + * This method should be used only for minting operations. + * @param outputs the outputs of the transaction + * @returns fee amount in HTR + * @memberof Fee + * @static + */ + static calculateTokenCreationTxFee(outputs: Omit[]): bigint { + return BigInt(Fee.getNonAuthorityTokenElement(outputs).length) * FEE_PER_OUTPUT; + } + + /** + * Filter the outputs to get only those that are not authority outputs. + * @param outputs outputs of the transaction + * @returns an array of outputs that are not authority outputs + * @memberof Fee + * @static + */ + static getNonAuthorityTokenElement( + outputs: (TokenElement | Omit)[] + ): (TokenElement | Omit)[] { + return outputs.filter(output => !Fee.isAuthorityTokenElement(output as never)); // casting to never since we don't need the token property here. + } + + /** + * Check if the token element is an authority by checking the `isAuthority` method or the `authorities` property. + * @param tokenElement token element to check + * @returns true if the token element is an authority, false otherwise + * @memberof Fee + * @static + */ + static isAuthorityTokenElement(tokenElement: TokenElement): boolean { + if (tokenElement instanceof Output) { + return tokenElement.isAuthority(); + } + return tokenElement.authorities !== 0n; + } + + /** + * Check if the token element is a non-authority token element by checking the isAuthorityTokenElement method, then grouping them by token UID. + * @param tokenElements an array of token elements to check + * @returns a map where the keys are the token UIDs and the values are arrays of non-authority token elements for that token + * @memberof Fee + * @static + */ + static groupTokenElementsByTokenUid(tokenElements: TokenElement[]): Map { + const map = new Map(); + + for (const tokenElement of tokenElements) { + if (!Fee.isAuthorityTokenElement(tokenElement)) { + let tokenUid: string = ''; + if ('token' in tokenElement) { + tokenUid = tokenElement.token; + } + if ('tokenId' in tokenElement) { + tokenUid = tokenElement.tokenId; + } + if (!tokenUid) { + throw new Error('Token UID not found in token element'); + } + if (!map.has(tokenUid)) { + map.set(tokenUid, []); + } + map.get(tokenUid)?.push(tokenElement); + } + } + return map; + } +} diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 31d0f54f9..db8e76bb6 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -36,6 +36,7 @@ import { import { ErrorMessages } from '../errorMessages'; import config from '../config'; import { IDataInput, IUtxo } from '../types'; +import { Utxo } from '../wallet/types'; /** * Helper methods @@ -390,7 +391,17 @@ const helpers = { }; if (data.version === CREATE_TOKEN_TX_VERSION) { - return new CreateTokenTransaction(data.name, data.symbol, inputs, outputs, options); + const createTokenOptions = { + ...options, + tokenVersion: data.tokenVersion, + }; + return new CreateTokenTransaction( + data.name, + data.symbol, + inputs, + outputs, + createTokenOptions + ); } if (data.version === DEFAULT_TX_VERSION) { return new Transaction(inputs, outputs, options); @@ -638,6 +649,15 @@ const helpers = { return 'privatenet'; }, + + /** + * Parse a Utxo to an Input without filling the options. + * @param utxo utxo to be parsed + * @returns {Input} Input object + */ + parseToInput(utxo: IUtxo | Utxo | { txId: string; index: number }): Input { + return new Input(utxo.txId, utxo.index); + }, }; export default helpers; diff --git a/src/utils/storage.ts b/src/utils/storage.ts index 943d86bf3..d61c6f042 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -24,6 +24,7 @@ import { WalletType, IUtxo, ITokenData, + TokenVersion, } from '../types'; import walletApi from '../api/wallet'; import helpers from './helpers'; @@ -509,7 +510,9 @@ export async function processMetadataChanged(storage: IStorage, tx: IHistoryTx): export async function _updateTokensData(storage: IStorage, tokens: Set): Promise { async function fetchTokenData( uid: string - ): Promise { + ): Promise< + GeneralTokenInfoSchema | { success: true; name: string; symbol: string; version?: TokenVersion } + > { let retryCount = 0; if (uid === NATIVE_TOKEN_UID) { @@ -518,6 +521,7 @@ export async function _updateTokensData(storage: IStorage, tokens: Set): success: true, name: nativeToken.name, symbol: nativeToken.symbol, + version: nativeToken.version, }; } @@ -557,8 +561,8 @@ export async function _updateTokensData(storage: IStorage, tokens: Set): throw new Error(response.message); } - const { name, symbol } = response; - const tokenData = { uid, name, symbol }; + const { name, symbol, version } = response; + const tokenData: ITokenData = { uid, name, symbol, version: version ?? undefined }; await storage.addToken(tokenData); } @@ -1004,6 +1008,7 @@ export async function addCreatedTokenFromTx( uid: tx.hash, name: tx.name, symbol: tx.symbol, + version: tx.tokenVersion, }; await storage.addToken(tokenInfo); diff --git a/src/utils/tokens.ts b/src/utils/tokens.ts index 967037be8..49e0d513a 100644 --- a/src/utils/tokens.ts +++ b/src/utils/tokens.ts @@ -6,6 +6,8 @@ */ import buffer from 'buffer'; +import FeeHeader from '../headers/fee'; +import Header from '../headers/base'; import { CREATE_TOKEN_TX_VERSION, NATIVE_TOKEN_UID, @@ -18,16 +20,24 @@ import helpers from './helpers'; import { IDataInput, IDataOutput, + IDataOutputWithToken, IDataTx, IStorage, ITokenData, OutputValueType, UtxoSelectionAlgorithm, + TokenVersion, } from '../types'; import { getAddressType } from './address'; -import { InsufficientFundsError, TokenValidationError } from '../errors'; +import { + InsufficientFundsError, + SendTxError, + TokenNotFoundError, + TokenValidationError, +} from '../errors'; import { bestUtxoSelection } from './utxo'; import walletApi from '../api/wallet'; +import { Fee } from './fee'; const tokens = { /** @@ -210,6 +220,37 @@ const tokens = { return { uid, name, symbol }; }, + /** + * Gets the default custom token version. Before the custom token versioning system was implemented, + * all tokens were created with the same version (DEPOSIT). + * @returns {TokenVersion} The default custom token version to be used when creating a token + * @memberof Tokens + * @inner + */ + getDefaultCustomTokenVersion(): TokenVersion { + return TokenVersion.DEPOSIT; + }, + + /** + * Receive a tokenData without an version and set it to the default version. + * **NOTE**: HTR tokens doesn't have a version, so we don't set it. + * @returns {ITokenData} The tokenData with the default version set. + * @memberof Tokens + * @inner + */ + setDefaultTokenVersion(tokenData: ITokenData): ITokenData { + if (!tokenData.uid) { + throw new Error('Token uid is required to set the default token version'); + } + if (!this.isHathorToken(tokenData.uid) && !tokenData.version) { + return { + ...tokenData, + version: this.getDefaultCustomTokenVersion(), + } satisfies ITokenData; + } + return tokenData; + }, + /** * Gets the token index to be added to the tokenData in the output from tx * @@ -221,7 +262,7 @@ const tokens = { * @memberof Tokens * @inner */ - getTokenIndex(tokensArray: ITokenData[], uid: string): number { + getTokenIndex(tokensArray: Partial[], uid: string): number { // If token is Hathor, index is always 0 // Otherwise, it is always the array index + 1 if (uid === NATIVE_TOKEN_UID) { @@ -319,7 +360,8 @@ const tokens = { * @param {boolean|null} [options.unshiftData=null] Whether to unshift the data script output. * @param {string[]|null} [options.data=null] list of data strings using utf8 encoding to add each as a data script output * @param {function} [options.utxoSelection=bestUtxoSelection] Algorithm to select utxos. Use the best method by default - * @param {boolean} [options.skipDepositFee=false] if it should skip utxo selection for token deposit fee + * @param {boolean} [options.skipDepositFee=false] if it should skip utxo selection for token fees + * @param {TokenVersion} [options.tokenVersion=TokenVersion.DEPOSIT] Token version to be used for the transaction * * @returns {Promise} The transaction data */ @@ -337,6 +379,7 @@ const tokens = { mintAuthorityAddress = null, utxoSelection = bestUtxoSelection, skipDepositFee = false, + tokenVersion = TokenVersion.DEPOSIT, }: { token?: string | null; mintInput?: IDataInput | null; @@ -347,49 +390,32 @@ const tokens = { mintAuthorityAddress?: string | null; utxoSelection?: UtxoSelectionAlgorithm; skipDepositFee?: boolean; - } = {} + tokenVersion: TokenVersion; + } ): Promise { const inputs: IDataInput[] = []; const outputs: IDataOutput[] = []; - let depositAmount = 0n; - // We might have transactions where the nano contract will pay for deposit fees - // so we must consider the skipDepositFee flag to skip the utxo selection - if (!skipDepositFee) { - depositAmount += this.getTransactionHTRDeposit(amount, data?.length ?? 0, storage); - } - - if (depositAmount) { - // get HTR deposit inputs - const selectedUtxos = await utxoSelection(storage, NATIVE_TOKEN_UID, depositAmount); - const foundAmount = selectedUtxos.amount; - for (const utxo of selectedUtxos.utxos) { - inputs.push(helpers.getDataInputFromUtxo(utxo)); - } + // variable that will be overridden when minting a token, so we can use the token version from the token data + // when creating a token, we use the token version passed as parameter + let _tokenVersion: TokenVersion = tokenVersion; - if (foundAmount < depositAmount) { - const availableAmount = selectedUtxos.available ?? 0; - throw new InsufficientFundsError( - `Not enough HTR tokens for deposit: ${depositAmount} required, ${availableAmount} available` - ); - } - - // get output change - if (foundAmount > depositAmount) { - const cAddress = await storage.getChangeAddress({ changeAddress }); + const isMintingToken = token !== null; + if (!isMintingToken && !tokenVersion) { + throw new Error('Token version is required when creating a token'); + } + const tokensArray = isMintingToken ? [token] : []; - outputs.push({ - type: getAddressType(cAddress, storage.config.getNetwork()), - address: cAddress, - value: foundAmount - depositAmount, - timelock: null, - token: NATIVE_TOKEN_UID, - authorities: 0n, - isChange: true, - }); + // check in the wallet storage if it has the token + if (isMintingToken) { + const tokenData = await storage.getToken(token); + if (!tokenData) { + throw new SendTxError(`Token ${token} not found.`); } + _tokenVersion = tokenData.version!; } + // mintInput if (mintInput !== null) { // We are spending a mint input to mint more tokens inputs.push(mintInput); @@ -415,6 +441,92 @@ const tokens = { }); } + // read fee amount as deposit when dealing with deposit tokens. + let depositAmount = 0n; + let feeAmount = 0n; + + switch (_tokenVersion) { + case TokenVersion.DEPOSIT: + // We might have transactions where the nano contract will pay for deposit fees + // so we must consider the skipDepositFee flag to skip the utxo selection + if (!skipDepositFee) { + depositAmount += this.getTransactionHTRDeposit(amount, data?.length ?? 0, storage); + } + break; + case TokenVersion.FEE: + // is creating a new token + if (skipDepositFee) { + feeAmount = 0n; + } else if (!isMintingToken) { + feeAmount = Fee.calculateTokenCreationTxFee(outputs); + } else { + const mappedOutputs = outputs.map( + output => + ({ + ...output, + token: token!, + }) satisfies IDataOutputWithToken + ); + // since we control the inputs, we can assume we don't have any melt operation that should be charged at this point. + // so we can pass an empty array for inputs + feeAmount = await Fee.calculate( + [], + mappedOutputs, + await tokens.getTokensByManyIds(storage, new Set(tokensArray)) + ); + + if (data) { + // The deposit amount will be the quantity of data strings in the array + // multiplied by the fee (this fee is not related to the trasanction fee that is calculated based in the token version) + depositAmount += this.getDataFee(data.length); + } + } + break; + default: + throw new Error('Invalid token version'); + } + + // get HTR deposit inputs + // we are using a sum because fee will be always 0 when we have a deposit token and vice versa + const requiredAmount = depositAmount + feeAmount; + if (requiredAmount > 0) { + const selectedUtxos = await utxoSelection(storage, NATIVE_TOKEN_UID, requiredAmount); + const foundAmount = selectedUtxos.amount; + for (const utxo of selectedUtxos.utxos) { + inputs.push(helpers.getDataInputFromUtxo(utxo)); + } + + if (foundAmount < requiredAmount) { + const availableAmount = selectedUtxos.available ?? 0; + throw new InsufficientFundsError( + `Not enough HTR tokens for deposit or fee: ${requiredAmount} required, ${availableAmount} available` + ); + } + + // get output change + if (foundAmount > requiredAmount) { + const cAddress = await storage.getChangeAddress({ changeAddress }); + + // place at the beginning of the array to keep the order of the outputs + outputs.unshift({ + type: getAddressType(cAddress, storage.config.getNetwork()), + address: cAddress, + value: foundAmount - requiredAmount, + timelock: null, + token: NATIVE_TOKEN_UID, + authorities: 0n, + isChange: true, + }); + } + } + + const headers: Header[] = []; + if (feeAmount > 0) { + const feeHeader = new FeeHeader([{ tokenIndex: 0, amount: feeAmount }]); + headers.push(feeHeader); + } + + // data outputs uses HTR so it doesn't count for the fee calculation and we can add them here if (data !== null) { for (const dataString of data) { const outputData = { @@ -437,12 +549,13 @@ const tokens = { } } - const tokensArray = token !== null ? [token] : []; - return { inputs, outputs, tokens: tokensArray, + // append the token version if we are creating a new token + ...(!isMintingToken ? { tokenVersion: _tokenVersion } : {}), + headers, }; }, @@ -489,30 +602,43 @@ const tokens = { throw new Error('Melt authority input is not valid'); } const inputs: IDataInput[] = [authorityMeltInput]; - const outputs: IDataOutput[] = []; + const outputs: IDataOutputWithToken[] = []; const tokensArray = [authorityMeltInput.token]; - const depositPercent = storage.getTokenDepositPercentage(); - let withdrawAmount = this.getWithdrawAmount(amount, depositPercent); + + // check in the wallet storage if it has the token + const tokenData = await storage.getToken(token); + if (!tokenData) { + throw new SendTxError(`Token ${token} not found.`); + } + + let withdrawAmount = 0n; + // The deposit amount will be the quantity of data strings in the array // multiplied by the fee or 0 if there are no data outputs + // it will be required even when dealing with fee based tokens let depositAmount = data !== null ? this.getDataScriptOutputFee() * BigInt(data.length) : 0n; - // We only make these calculations if we are creating data outputs because the transaction needs to deposit the fee - if (depositAmount > 0) { - // If we are creating data outputs the withdrawal amount may be used to create the data outputs - // This may prevent finding HTR inputs to meet the deposit amount if we are creating HTR with the melt. - if (withdrawAmount >= depositAmount) { - // We can use part of the withdraw tokens as deposit - withdrawAmount -= depositAmount; - depositAmount = 0n; - } else { - // Deposit is greater than withdraw, we will use all withdrawn tokens and still need to find utxos to meet deposit - depositAmount -= withdrawAmount; - withdrawAmount = 0n; + if (tokenData.version === TokenVersion.DEPOSIT) { + const depositPercent = storage.getTokenDepositPercentage(); + withdrawAmount = this.getWithdrawAmount(amount, depositPercent); + + // We only make these calculations if we are creating data outputs because the transaction needs to deposit the fee + if (depositAmount > 0) { + // If we are creating data outputs the withdrawal amount may be used to create the data outputs + // This may prevent finding HTR inputs to meet the deposit amount if we are creating HTR with the melt. + if (withdrawAmount >= depositAmount) { + // We can use part of the withdraw tokens as deposit + withdrawAmount -= depositAmount; + depositAmount = 0n; + } else { + // Deposit is greater than withdraw, we will use all withdrawn tokens and still need to find utxos to meet deposit + depositAmount -= withdrawAmount; + withdrawAmount = 0n; + } } } - // get inputs that amount to requested melt amount + // get token inputs that amount to requested melt amount const selectedUtxos = await utxoSelection(storage, token, amount); const foundAmount = selectedUtxos.amount; for (const utxo of selectedUtxos.utxos) { @@ -526,7 +652,7 @@ const tokens = { ); } - // get output change + // get token output change if (foundAmount > amount) { const cAddress = await storage.getChangeAddress({ changeAddress }); @@ -541,36 +667,6 @@ const tokens = { }); } - if (depositAmount > 0) { - // get HTR deposit inputs - const depositSelectedUtxos = await utxoSelection(storage, NATIVE_TOKEN_UID, depositAmount); - const depositFoundAmount = depositSelectedUtxos.amount; - for (const utxo of depositSelectedUtxos.utxos) { - inputs.push(helpers.getDataInputFromUtxo(utxo)); - } - - if (depositFoundAmount < depositAmount) { - throw new InsufficientFundsError( - `Not enough HTR tokens for deposit: ${depositAmount} required, ${depositFoundAmount} available` - ); - } - - // get output change - if (depositFoundAmount > depositAmount) { - const cAddress = await storage.getChangeAddress({ changeAddress }); - - outputs.push({ - type: getAddressType(cAddress, storage.config.getNetwork()), - address: cAddress, - value: depositFoundAmount - depositAmount, - timelock: null, - token: NATIVE_TOKEN_UID, - authorities: 0n, - isChange: true, - }); - } - } - if (createAnotherMelt) { const newAddress = meltAuthorityAddress || (await storage.getCurrentAddress()); outputs.push({ @@ -584,7 +680,7 @@ const tokens = { } // When melting an amount smaller than 100 (1.00), the withdraw value will be 0, then we don't need to add output for that - if (withdrawAmount > 0) { + if (withdrawAmount > 0 && tokenData.version === TokenVersion.DEPOSIT) { outputs.push({ value: withdrawAmount, address, @@ -595,6 +691,44 @@ const tokens = { }); } + // calculate the transaction fee and add it to the headers + const feeAmount = await Fee.calculate(inputs, outputs, new Map([[tokenData.uid, tokenData]])); + const headers: Header[] = []; + if (feeAmount > 0) { + headers.push(new FeeHeader([{ tokenIndex: 0, amount: feeAmount }])); + } + + const requiredAmount = depositAmount + feeAmount; + if (requiredAmount > 0) { + // get HTR required inputs to pay the deposit + fee; + const htrSelectedUtxos = await utxoSelection(storage, NATIVE_TOKEN_UID, requiredAmount); + const htrFoundAmount = htrSelectedUtxos.amount; + for (const utxo of htrSelectedUtxos.utxos) { + inputs.push(helpers.getDataInputFromUtxo(utxo)); + } + + if (htrFoundAmount < requiredAmount) { + throw new InsufficientFundsError( + `Not enough HTR tokens for deposit or fee: ${requiredAmount} required, ${htrFoundAmount} available` + ); + } + + // get output change + if (htrFoundAmount > requiredAmount) { + const cAddress = await storage.getChangeAddress({ changeAddress }); + + outputs.push({ + type: getAddressType(cAddress, storage.config.getNetwork()), + address: cAddress, + value: htrFoundAmount - requiredAmount, + timelock: null, + token: NATIVE_TOKEN_UID, + authorities: 0n, + isChange: true, + }); + } + } + if (data !== null) { for (const dataString of data) { const outputData = { @@ -603,7 +737,7 @@ const tokens = { value: 1n, token: NATIVE_TOKEN_UID, authorities: 0n, - } as IDataOutput; + } as IDataOutputWithToken; if (unshiftData) { outputs.unshift(outputData); @@ -617,6 +751,7 @@ const tokens = { inputs, outputs, tokens: tokensArray, + headers, }; }, @@ -654,6 +789,7 @@ const tokens = { data = null, isCreateNFT = false, skipDepositFee = false, + tokenVersion = TokenVersion.DEPOSIT, }: { changeAddress?: string | null; createMint?: boolean; @@ -663,6 +799,7 @@ const tokens = { data?: string[] | null; isCreateNFT?: boolean; skipDepositFee?: boolean; + tokenVersion?: TokenVersion; } = {} ): Promise { const mintOptions = { @@ -672,6 +809,7 @@ const tokens = { unshiftData: isCreateNFT, data, skipDepositFee, + tokenVersion, }; const txData = await this.prepareMintTxData(address, mintAmount, storage, mintOptions); @@ -696,6 +834,8 @@ const tokens = { txData.version = CREATE_TOKEN_TX_VERSION; txData.name = name; txData.symbol = symbol; + // Version of the token being created + txData.tokenVersion = tokenVersion; return txData; }, @@ -801,6 +941,23 @@ const tokens = { const depositPercent = storage.getTokenDepositPercentage(); return this.getDepositAmount(mintAmount, depositPercent); }, + + /** + * Get tokens from the wallet + * @param storage Storage with tokens within + * @param ids ids to search by + */ + async getTokensByManyIds(storage: IStorage, ids: Set): Promise> { + const _tokens = new Map(); + for await (const tokenUid of ids) { + const tokenData = await storage.getToken(tokenUid); + if (!tokenData) { + throw new TokenNotFoundError(tokenUid); + } + _tokens.set(tokenUid, tokenData); + } + return _tokens; + }, }; export default tokens; diff --git a/src/utils/transaction.ts b/src/utils/transaction.ts index 7e88966ed..0fd29f98a 100644 --- a/src/utils/transaction.ts +++ b/src/utils/transaction.ts @@ -330,9 +330,11 @@ const transaction = { throw new UtxoError("Don't have enough utxos to fill total amount."); } + const changeAmount = filledAmount - totalAmount; + return { utxos: utxosToUse, - changeAmount: filledAmount - totalAmount, + changeAmount, }; }, @@ -610,9 +612,20 @@ const transaction = { timestamp: txData.timestamp || null, parents: txData.parents || [], tokens: txData.tokens || [], + headers: txData.headers || [], }; if (options.version === CREATE_TOKEN_TX_VERSION) { - return new CreateTokenTransaction(txData.name!, txData.symbol!, inputs, outputs, options); + const createTokenOptions = { + ...options, + tokenVersion: txData.tokenVersion, + }; + return new CreateTokenTransaction( + txData.name!, + txData.symbol!, + inputs, + outputs, + createTokenOptions + ); } if (options.version === DEFAULT_TX_VERSION) { return new Transaction(inputs, outputs, options); diff --git a/src/wallet/api/schemas/walletApi.ts b/src/wallet/api/schemas/walletApi.ts index 59b826cba..2047e9efb 100644 --- a/src/wallet/api/schemas/walletApi.ts +++ b/src/wallet/api/schemas/walletApi.ts @@ -9,6 +9,7 @@ import { z } from 'zod'; import { NATIVE_TOKEN_UID } from '../../../constants'; import { txIdSchema } from '../../../schemas'; import { bigIntCoercibleSchema } from '../../../utils/bigint'; +import { TokenVersion } from '../../../types'; /** * Schema for validating Hathor addresses. @@ -110,6 +111,7 @@ export const tokenInfoSchema = z.object({ id: tokenIdSchema, name: z.string(), symbol: z.string(), + version: z.nativeEnum(TokenVersion), }); /** diff --git a/src/wallet/api/walletApi.ts b/src/wallet/api/walletApi.ts index 646e8ebc1..05475a23f 100644 --- a/src/wallet/api/walletApi.ts +++ b/src/wallet/api/walletApi.ts @@ -183,7 +183,7 @@ const walletApi = { if (response.status === 200 && response.data.success === true) { return parseSchema(response.data, tokenDetailsResponseSchema); } - throw new WalletRequestError('Error getting token details.'); + throw new WalletRequestError(`Error getting token ${tokenId} details.`); }, async getBalances( diff --git a/src/wallet/types.ts b/src/wallet/types.ts index ea10d3935..1cdc2ca04 100644 --- a/src/wallet/types.ts +++ b/src/wallet/types.ts @@ -6,12 +6,12 @@ */ import bitcore from 'bitcore-lib'; +import { TokenVersion, IStorage, OutputValueType, IHistoryTx } from '../types'; import Transaction from '../models/transaction'; import CreateTokenTransaction from '../models/create_token_transaction'; import SendTransactionWalletService from './sendTransactionWalletService'; import Input from '../models/input'; import Output from '../models/output'; -import { IStorage, OutputValueType, IHistoryTx } from '../types'; import { CreateNanoTxData } from '../nano_contracts/types'; // Type used in create token methods so we can have defaults for required params @@ -52,6 +52,7 @@ export interface TokenInfo { id: string; // Token id name: string; // Token name symbol: string; // Token symbol + version: TokenVersion; // Token version } export interface Balance { diff --git a/src/wallet/wallet.ts b/src/wallet/wallet.ts index 4bf880800..07bcf58ef 100644 --- a/src/wallet/wallet.ts +++ b/src/wallet/wallet.ts @@ -8,6 +8,8 @@ import { EventEmitter } from 'events'; import bitcore, { util } from 'bitcore-lib'; import assert from 'assert'; +import Header from '../headers/base'; +import FeeHeader from '../headers/fee'; import { NATIVE_TOKEN_UID, TOKEN_MINT_MASK, @@ -75,9 +77,8 @@ import { UninitializedWalletError, WalletFromXPubGuard, PinRequiredError, + TokenNotFoundError, } from '../errors'; -import { ErrorMessages } from '../errorMessages'; -import { IStorage, IWalletAccessData, OutputValueType, WalletType, IHistoryTx } from '../types'; import NanoContractTransactionBuilder from '../nano_contracts/builder'; import { NanoContractVertexType, @@ -86,6 +87,18 @@ import { } from '../nano_contracts/types'; import { WalletServiceStorageProxy } from './walletServiceStorageProxy'; import HathorWallet from '../new/wallet'; +import { ErrorMessages } from '../errorMessages'; +import { + IStorage, + IWalletAccessData, + OutputValueType, + IHistoryTx, + IDataOutputWithToken, + WalletType, + ITokenData, + TokenVersion, +} from '../types'; +import { Fee } from '../utils/fee'; // Time in milliseconds berween each polling to check wallet status // if it ended loading and became ready @@ -1680,6 +1693,7 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { isCreateNFT: boolean; pinCode: string | null; signTx: boolean; + tokenVersion: TokenVersion | null; }; const newOptions: optionsType = { address: null, @@ -1694,6 +1708,7 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { isCreateNFT: false, pinCode: null, signTx: true, + tokenVersion: TokenVersion.DEPOSIT, ...options, }; @@ -1712,34 +1727,20 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { throw new SendTxError('The melt authority address must belong to your wallet.'); } } + const tokenVersion = newOptions.tokenVersion || TokenVersion.DEPOSIT; - const depositPercent = this.storage.getTokenDepositPercentage(); // 1. Calculate HTR deposit needed - let deposit = tokens.getDepositAmount(amount, depositPercent); + let deposit = 0n; + if (tokenVersion === TokenVersion.DEPOSIT) { + const depositPercent = this.storage.getTokenDepositPercentage(); + deposit += tokens.getDepositAmount(amount, depositPercent); + } if (newOptions.data && newOptions.data.length > 0) { - // For data outputs, we have a fee of 0.01 HTR per data output + // We require a 0.01 HTR fee for each data output created deposit += tokens.getDataFee(newOptions.data.length); } - // 2. Get utxos for HTR - const { utxos, changeAmount } = await this.getUtxosForAmount(deposit, { - token: NATIVE_TOKEN_UID, - }); - if (utxos.length === 0) { - throw new UtxoError( - `No utxos available to fill the request. Token: HTR - Amount: ${deposit}.` - ); - } - - const utxosAddressPath: string[] = []; - // 3. Create the transaction object with the inputs and outputs (new token amount, change address with HTR, mint/melt authorities - depending on parameters) - const inputsObj: Input[] = []; - for (const utxo of utxos) { - inputsObj.push(new Input(utxo.txId, utxo.index)); - utxosAddressPath.push(utxo.addressPath); - } - // Create outputs const outputsObj: Output[] = []; const dataOutputs: Output[] = []; @@ -1749,56 +1750,57 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { } } + // insert the data outputs in the beggining of the array, in case it isn't a NFT it will be added at the end of the array if (newOptions.isCreateNFT && dataOutputs.length > 0) { outputsObj.push(...dataOutputs); } // a. Token amount - const addressToUse = newOptions.address || this.getCurrentAddress({ markAsUsed: true }).address; - const address = new Address(addressToUse, { network: this.network }); - if (!address.isValid()) { - throw new SendTxError(`Address ${newOptions.address} is not valid.`); - } + const address = this.validateAddress(newOptions.address); const p2pkhScript = address.getScript(); outputsObj.push(new Output(amount, p2pkhScript, { tokenData: 1 })); if (newOptions.createMint) { // b. Mint authority - const mintAuthorityAddress = - newOptions.mintAuthorityAddress || this.getCurrentAddress({ markAsUsed: true }).address; - const mintAuthorityAddressObj = new Address(mintAuthorityAddress, { network: this.network }); - if (!mintAuthorityAddressObj.isValid()) { - throw new SendTxError(`Address ${newOptions.mintAuthorityAddress} is not valid.`); - } - + const mintAuthorityAddressObj = this.validateAddress(newOptions.mintAuthorityAddress); const p2pkhMintAuthorityScript = mintAuthorityAddressObj.getScript(); outputsObj.push( new Output(TOKEN_MINT_MASK, p2pkhMintAuthorityScript, { tokenData: AUTHORITY_TOKEN_DATA }) ); } + // 2. Calculate the fee, we are using a simplified fee calculation since in this method we only have outputs related to the token creation + // Data outputs are not included in this fee calculation because they have their own fee (0.01 HTR per data output) + let fee = 0n; + if (tokenVersion === TokenVersion.FEE) { + fee = Fee.calculateTokenCreationTxFee([...outputsObj]); + } + + const headers: Header[] = []; + if (fee > 0) { + headers.push(new FeeHeader([{ tokenIndex: 0, amount: fee }])); + } + + // 3. Get utxos for HTR + const totalAmount = deposit + fee; + const { utxos, changeAmount } = await this.getUtxosForAmount(totalAmount, { + token: NATIVE_TOKEN_UID, + }); + if (utxos.length === 0) { + throw new UtxoError( + `No utxos available to fill the request. Token: HTR - Amount: ${totalAmount}.` + ); + } + if (changeAmount) { // c. HTR change output - const changeAddressStr = - newOptions.changeAddress || this.getCurrentAddress({ markAsUsed: true }).address; - const changeAddress = new Address(changeAddressStr, { network: this.network }); - if (!changeAddress.isValid()) { - throw new SendTxError(`Address ${newOptions.changeAddress} is not valid.`); - } - const p2pkhChange = new P2PKH(changeAddress); - const p2pkhChangeScript = p2pkhChange.createScript(); - outputsObj.push(new Output(changeAmount, p2pkhChangeScript)); + outputsObj.push(this.createOutput(changeAmount, newOptions.changeAddress)); } if (newOptions.createMelt) { // d. Melt authority - const meltAuthorityAddress = - newOptions.meltAuthorityAddress || this.getCurrentAddress({ markAsUsed: true }).address; - const meltAuthorityAddressObj = new Address(meltAuthorityAddress, { network: this.network }); - if (!meltAuthorityAddressObj.isValid()) { - throw new SendTxError(`Address ${newOptions.meltAuthorityAddress} is not valid.`); - } + const meltAuthorityAddressObj = this.validateAddress(newOptions.meltAuthorityAddress); const p2pkhMeltAuthorityScript = meltAuthorityAddressObj.getScript(); outputsObj.push( @@ -1806,11 +1808,23 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { ); } + const utxosAddressPath: string[] = []; + // 3. Create the transaction object with the inputs and outputs (new token amount, change address with HTR, mint/melt authorities - depending on parameters) + const inputsObj: Input[] = []; + for (const utxo of utxos) { + inputsObj.push(new Input(utxo.txId, utxo.index)); + utxosAddressPath.push(utxo.addressPath); + } + + // if it isn't a NFT, add the data outputs at the end of the array if (!newOptions.isCreateNFT && dataOutputs.length > 0) { outputsObj.push(...dataOutputs); } - const tx = new CreateTokenTransaction(name, symbol, inputsObj, outputsObj); + const tx = new CreateTokenTransaction(name, symbol, inputsObj, outputsObj, { + tokenVersion, + headers, + }); // Sign transaction if (newOptions.signTx) { @@ -2046,21 +2060,21 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { } } - // 1. Calculate HTR deposit needed - const depositPercent = this.storage.getTokenDepositPercentage(); - const deposit = tokens.getDepositAmount(amount, depositPercent); + // Get token info + const { tokenInfo } = await this.getTokenDetails(token); - // 2. Get utxos for HTR - const { utxos, changeAmount } = await this.getUtxosForAmount(deposit, { - token: NATIVE_TOKEN_UID, - }); - if (utxos.length === 0) { - throw new UtxoError( - `No utxos available to fill the request. Token: HTR - Amount: ${deposit}.` - ); + if (!tokenInfo) { + throw new TokenNotFoundError(token); } - // 3. Get mint authority + // 1. Calculate HTR deposit needed + let deposit = 0n; + if (tokenInfo?.version === TokenVersion.DEPOSIT) { + const depositPercent = this.storage.getTokenDepositPercentage(); + deposit = tokens.getDepositAmount(amount, depositPercent); + } + + // 2. Get mint authority const mintAuthorities = await this.getMintAuthority(token, { many: false, skipSpent: true }); if (mintAuthorities.length === 0) { throw new UtxoError(`No authority utxo available for minting tokens. Token: ${token}.`); @@ -2068,55 +2082,59 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { // it's safe to assume that we have an utxo in the array const mintUtxo = mintAuthorities[0]; - // 4. Create inputs from utxos - const inputsObj: Input[] = []; - for (const utxo of utxos) { - // First add HTR utxos - inputsObj.push(new Input(utxo.txId, utxo.index)); - } - - // Then add a single mint authority utxo - inputsObj.push(new Input(mintUtxo.txId, mintUtxo.index)); - // Create outputs const outputsObj: Output[] = []; // a. Token amount - const addressToUse = newOptions.address || this.getCurrentAddress({ markAsUsed: true }).address; - const address = new Address(addressToUse, { network: this.network }); - if (!address.isValid()) { - throw new SendTxError(`Address ${newOptions.address} is not valid.`); - } - const p2pkhScript = address.getScript(); - outputsObj.push(new Output(amount, p2pkhScript, { tokenData: 1 })); + outputsObj.push(this.createOutput(amount, newOptions.address, 1)); if (newOptions.createAnotherMint) { // b. Mint authority - const authorityAddress = - newOptions.mintAuthorityAddress || this.getCurrentAddress({ markAsUsed: true }).address; - const authorityAddressObj = new Address(authorityAddress, { network: this.network }); - if (!authorityAddressObj.isValid()) { - throw new SendTxError(`Address ${newOptions.mintAuthorityAddress} is not valid.`); - } + const authorityAddressObj = this.validateAddress(newOptions.mintAuthorityAddress); const p2pkhAuthorityScript = authorityAddressObj.getScript(); outputsObj.push( new Output(TOKEN_MINT_MASK, p2pkhAuthorityScript, { tokenData: AUTHORITY_TOKEN_DATA }) ); } + const mappedOutputs = outputsObj.map(output => this.mapToDataOutput(output, token)); + + // We pass an empty array in the Inputs, because we are minting and won't hit the edge case of melting without outputs + const _tokens = new Map(); + _tokens.set(tokenInfo.id, { ...tokenInfo, uid: tokenInfo.id }); + + const fee = await Fee.calculate([], mappedOutputs, _tokens); + const headers: Header[] = []; + if (fee > 0) { + headers.push(new FeeHeader([{ tokenIndex: 0, amount: fee }])); + } + + // 4. Get utxos for HTR + const totalAmount = deposit + fee; + const { utxos, changeAmount } = await this.getUtxosForAmount(totalAmount, { + token: NATIVE_TOKEN_UID, + }); + if (utxos.length === 0) { + throw new UtxoError( + `No utxos available to fill the request. Token: HTR - Amount: ${totalAmount}.` + ); + } + + // 3. Create inputs from utxos + const inputsObj: Input[] = []; + for (const utxo of utxos) { + // First add HTR utxos + inputsObj.push(helpers.parseToInput(utxo)); + } + + // Then add a single mint authority utxo + inputsObj.push(helpers.parseToInput(mintUtxo)); + if (changeAmount) { // c. HTR change output - const changeAddressStr = - newOptions.changeAddress || this.getCurrentAddress({ markAsUsed: true }).address; - const changeAddress = new Address(changeAddressStr, { network: this.network }); - if (!changeAddress.isValid()) { - throw new SendTxError(`Address ${newOptions.changeAddress} is not valid.`); - } - const p2pkhChange = new P2PKH(changeAddress); - const p2pkhChangeScript = p2pkhChange.createScript(); - outputsObj.push(new Output(changeAmount, p2pkhChangeScript)); + outputsObj.push(this.createOutput(changeAmount, newOptions.changeAddress)); } - const tx = new Transaction(inputsObj, outputsObj); + const tx = new Transaction(inputsObj, outputsObj, { headers }); tx.tokens = [token]; // Sign transaction @@ -2221,13 +2239,22 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { } } - // 1. Calculate HTR deposit needed - const depositPercent = this.storage.getTokenDepositPercentage(); - const withdraw = tokens.getWithdrawAmount(amount, depositPercent); + // Get token info + const tokenData = await this.storage.getToken(token); + if (!tokenData) { + throw new SendTxError(`Token ${token} not found.`); + } + + // 1. Calculate HTR withdraw + let withdraw = 0n; + if (tokenData?.version === TokenVersion.DEPOSIT) { + const depositPercent = this.storage.getTokenDepositPercentage(); + withdraw = tokens.getWithdrawAmount(amount, depositPercent); + } // 2. Get utxos for custom token to melt - const { utxos, changeAmount } = await this.getUtxosForAmount(amount, { token }); - if (utxos.length === 0) { + const { utxos: tokenUtxos, changeAmount } = await this.getUtxosForAmount(amount, { token }); + if (tokenUtxos.length === 0) { throw new UtxoError(`Not enough tokens to be melted. Token: ${token} - Amount: ${amount}.`); } @@ -2241,37 +2268,25 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { // 4. Create inputs from utxos const inputsObj: Input[] = []; - for (const utxo of utxos) { - // First add HTR utxos - inputsObj.push(new Input(utxo.txId, utxo.index)); + for (const utxo of tokenUtxos) { + inputsObj.push(helpers.parseToInput(utxo)); } - // Then add a single mint authority utxo (it's safe to assume that we have an utxo in the array) - inputsObj.push(new Input(meltUtxo.txId, meltUtxo.index)); + // Then add a single melt authority utxo (it's safe to assume that we have an utxo in the array) + inputsObj.push(helpers.parseToInput(meltUtxo)); // Create outputs const outputsObj: Output[] = []; - // a. Deposit back - const addressToUse = newOptions.address || this.getCurrentAddress({ markAsUsed: true }).address; - const address = new Address(addressToUse, { network: this.network }); - if (!address.isValid()) { - throw new SendTxError(`Address ${newOptions.address} is not valid.`); - } - const p2pkh = new P2PKH(address); - const p2pkhScript = p2pkh.createScript(); + + // a. withdrawal + // We may have nothing to withdraw if (withdraw) { - // We may have nothing to get back - outputsObj.push(new Output(withdraw, p2pkhScript, { tokenData: 0 })); + outputsObj.push(this.createOutput(withdraw, newOptions.address, 0)); // token data is 0 because we are withdrawing HTR } if (newOptions.createAnotherMelt) { // b. Melt authority - const authorityAddress = - newOptions.meltAuthorityAddress || this.getCurrentAddress({ markAsUsed: true }).address; - const authorityAddressObj = new Address(authorityAddress, { network: this.network }); - if (!authorityAddressObj.isValid()) { - throw new SendTxError(`Address ${newOptions.meltAuthorityAddress} is not valid.`); - } + const authorityAddressObj = this.validateAddress(newOptions.meltAuthorityAddress); const p2pkhAuthorityScript = authorityAddressObj.getScript(); outputsObj.push( new Output(TOKEN_MELT_MASK, p2pkhAuthorityScript, { @@ -2282,18 +2297,44 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { if (changeAmount) { // c. Token change output - const changeAddressStr = - newOptions.changeAddress || this.getCurrentAddress({ markAsUsed: true }).address; - const changeAddress = new Address(changeAddressStr, { network: this.network }); - if (!changeAddress.isValid()) { - throw new SendTxError(`Address ${newOptions.changeAddress} is not valid.`); + outputsObj.push(this.createOutput(changeAmount, newOptions.changeAddress, 1)); + } + + const headers: Header[] = []; + if (tokenData?.version === TokenVersion.FEE) { + const mappedOutputs = outputsObj.map(output => this.mapToDataOutput(output, token)); + const fee = await Fee.calculate( + tokenUtxos, // we are using the token utxos instead of the inputs we need to check if this utxo is an authority utxo + mappedOutputs, + new Map([[tokenData.uid, tokenData]]) + ); + + if (fee > 0) { + headers.push(new FeeHeader([{ tokenIndex: 0, amount: fee }])); + } + + // Get utxos for HTR + const { utxos: htrUtxos, changeAmount: htrChangeAmount } = await this.getUtxosForAmount(fee, { + token: NATIVE_TOKEN_UID, + }); + + if (htrUtxos.length === 0) { + throw new UtxoError(`No utxos available to fill the request. Token: HTR - Amount: ${fee}.`); + } + + // Add HTR inputs + for (const utxo of htrUtxos) { + inputsObj.push(helpers.parseToInput(utxo)); + } + + // Htr isn't billable, so we can append it here after calculating the fee + if (htrChangeAmount) { + // HTR change output + outputsObj.push(this.createOutput(htrChangeAmount, newOptions.changeAddress)); } - const p2pkhChange = new P2PKH(changeAddress); - const p2pkhChangeScript = p2pkhChange.createScript(); - outputsObj.push(new Output(changeAmount, p2pkhChangeScript, { tokenData: 1 })); } - const tx = new Transaction(inputsObj, outputsObj); + const tx = new Transaction(inputsObj, outputsObj, { headers }); tx.tokens = [token]; // Sign transaction @@ -2319,7 +2360,7 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { } else { // This is a regular token input addressIndex = HathorWalletServiceWallet.getAddressIndexFromFullPath( - utxos[idx].addressPath + tokenUtxos[idx].addressPath ); } const inputData = this.getInputData(xprivkey, dataToSignHash, addressIndex); @@ -2331,6 +2372,62 @@ class HathorWalletServiceWallet extends EventEmitter implements IHathorWallet { return tx; } + private mapToDataOutput(output: Output, token: string) { + let authorities = 0n; + if (output.isAuthority()) { + if (output.isMint()) { + authorities = 1n; + } + if (output.isMelt()) { + authorities = 2n; + } + } + return { + token, + value: output.value, + authorities, + data: '', + type: output.getType(this.network) as never, + } satisfies IDataOutputWithToken; + } + + /** + * Generate a change output with the given amount. If the address is not provided, it will + * use the current address. + * @param amount Token amount + * @param address address string + * @param tokenData token data to be used in the output + * @returns an Output object + * @memberof HathorWalletServiceWallet + * @inner + * @throws SendTxError if the address is not valid + */ + private createOutput(amount: bigint, address: string | null, tokenData?: number): Output { + const addressObj = this.validateAddress(address); + return new Output(amount, new P2PKH(addressObj).createScript(), { tokenData }); + } + + /** + * Validate and throw if the provided address is not valid, it will use the current address if + * the address is not provided. + * @param address address string + * @returns the valid the address instance + * @memberof HathorWalletServiceWallet + * @inner + * @throws SendTxError if the address is not valid + */ + private validateAddress( + address: string | null, + { markAsUsed }: { markAsUsed: boolean } = { markAsUsed: true } + ): Address { + const _address = address || this.getCurrentAddress({ markAsUsed }).address; + const addressInstance = new Address(_address, { network: this.network }); + if (!addressInstance.isValid()) { + throw new SendTxError(`Address ${address} is not valid.`); + } + return addressInstance; + } + /** * Melt custom token units *