diff --git a/assets/config/v5/communities.json b/assets/config/v5/communities.json new file mode 100644 index 00000000..396deeb6 --- /dev/null +++ b/assets/config/v5/communities.json @@ -0,0 +1,2444 @@ +[ + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "cards": { + "137:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 137, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x0D9B0790E97e3426C161580dF4Ee853E4A7C4607": { + "name": "Citizen Wallet", + "symbol": "CTZN", + "address": "0x0D9B0790E97e3426C161580dF4Ee853E4A7C4607", + "chain_id": 137, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://citizenwallet.xyz/pay-with-ctzn", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/ctzn.svg", + "name": "About", + "launch_mode": "browser" + }, + { + "url": "https://my.citizenwallet.xyz/onramp", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/ctzn.svg", + "name": "Top Up", + "action": "topup", + "signature": true + } + ], + "version": 5, + "accounts": { + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x3A3E25871c5C6C84D5f397829FF316a37F7FD596", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "137:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 137, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/ctzn.svg", + "name": "Citizen Wallet (CTZN)", + "alias": "ctzn", + "theme": { + "primary": "#9563D3" + }, + "profile": { + "address": "0x8dA817724Eb6A2aA47c0F8d8b8A98b9B3C2Ddb68", + "chain_id": 137 + }, + "description": "The token powering the Citizen Wallet economy.", + "primary_token": { + "address": "0x0D9B0790E97e3426C161580dF4Ee853E4A7C4607", + "chain_id": 137 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/ctzn" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "100:0x1EaF6B6A6967608aF6c77224f087b042095891EB": { + "type": "classic", + "address": "0x1EaF6B6A6967608aF6c77224f087b042095891EB", + "chain_id": 100 + }, + "100:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100, + "instance_id": "brussels-pay" + } + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://engine.pay.brussels", + "ws_url": "wss://engine.pay.brussels" + } + } + }, + "tokens": { + "100:0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1": { + "name": "pay.brussels", + "symbol": "EURb", + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://checkout.pay.brussels/topup", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/wallet.pay.brussels.png", + "name": "Top Up", + "action": "topup", + "signature": true + } + ], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0xE69C843898E21C0E95eA7DD310cD850AAc0aB897", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "100:0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE": { + "chain_id": 100, + "paymaster_type": "cw", + "paymaster_address": "0xcA1B9EC1117340818C1c1fdd1B48Ea79E57C140F", + "entrypoint_address": "0xAAEb9DC18aDadae9b3aE7ec2b47842565A81113f", + "account_factory_address": "0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://pay.brussels", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/wallet.pay.brussels.png", + "name": "Brussels Pay", + "alias": "wallet.pay.brussels", + "theme": { + "primary": "#4a90e2" + }, + "hidden": false, + "profile": { + "address": "0x56Cc38bDa01bE6eC6D854513C995f6621Ee71229", + "chain_id": 100 + }, + "description": "A community for the city of Brussels", + "custom_domain": "wallet.pay.brussels", + "primary_token": { + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 100 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.pay.brussels" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "cards": { + "42220:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1": { + "name": "Gratitude Token", + "symbol": "GT", + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220, + "decimals": 0, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xF05ba2641b31AF70c2678e3324eD8b9C53093FbE", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8", + "entrypoint_address": "0x985ec7d08D9d15Ea79876E35FAdEFD58A627187E", + "account_factory_address": "0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz/gratitude", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/gt.svg", + "name": "Gratitude Token", + "alias": "gratitude", + "theme": { + "primary": "#4EC19D" + }, + "profile": { + "address": "0xEEc0F3257369c6bCD2Fd8755CbEf8A95b12Bc4c9", + "chain_id": 42220 + }, + "description": "Express your gratitude towards someone by sending them a token of gratitude.", + "primary_token": { + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/gratitude" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "cards": { + "80094:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 80094, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "80094": { + "id": 80094, + "node": { + "url": "https://80094.engine.citizenwallet.xyz", + "ws_url": "wss://80094.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "80094:0x881cad4f885c6701d8481c0ed347f6d35444ea7e": { + "name": "SFLUV V1.1", + "symbol": "SFLUV", + "address": "0x881cad4f885c6701d8481c0ed347f6d35444ea7e", + "chain_id": 80094, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://app.sfluv.org", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "About", + "hidden": true, + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "80094:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 80094, + "paymaster_type": "cw-safe", + "paymaster_address": "0x9A5be02B65f9Aa00060cB8c951dAFaBAB9B860cd", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "80094:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 80094, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://sfluv.org", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "SFLUV Community", + "alias": "wallet.berachain.sfluv.org", + "theme": { + "primary": "#eb6c6c" + }, + "profile": { + "address": "0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99", + "chain_id": 80094 + }, + "description": "A community currency for the city of San Francisco.", + "custom_domain": "wallet.sfluv.org", + "primary_token": { + "address": "0x881cad4f885c6701d8481c0ed347f6d35444ea7e", + "chain_id": 80094 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 80094 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 80094 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 80094 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.berachain.sfluv.org" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x58a2993A618Afee681DE23dECBCF535A58A080BA": { + "name": "SFLUV V1.1", + "symbol": "SFLUV", + "address": "0x58a2993A618Afee681DE23dECBCF535A58A080BA", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://app.sfluv.org", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "About", + "hidden": true, + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "137:0x5e987a6c4bb4239d498E78c34e986acf29c81E8e": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0x7FC98D0a2bd7f766bAca37388eB0F6Db37666B33", + "entrypoint_address": "0x2d01C5E40Aa6a8478eD0FFbF2784EBb9bf67C46A", + "account_factory_address": "0x5e987a6c4bb4239d498E78c34e986acf29c81E8e" + } + }, + "sessions": { + "137:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 137, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://sfluv.org", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "SFLUV Community (Polygon)", + "alias": "wallet.sfluv.org", + "theme": { + "primary": "#eb6c6c" + }, + "profile": { + "address": "0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99", + "chain_id": 137 + }, + "description": "A community currency for the city of San Francisco.", + "custom_domain": "wallet.polygon.sfluv.org", + "primary_token": { + "address": "0x58a2993A618Afee681DE23dECBCF535A58A080BA", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x5e987a6c4bb4239d498E78c34e986acf29c81E8e", + "chain_id": 137 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.sfluv.org" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://100.engine.citizenwallet.xyz", + "ws_url": "wss://100.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "100:0x6c6611244547a6E9AaCfBA8744115ca1076756fc": { + "name": "Txirrin", + "symbol": "TXI", + "address": "0x6c6611244547a6E9AaCfBA8744115ca1076756fc", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0x33500E7Eb3452421e56c2f4117530B1C4C85E0A5", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz/txirrin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/txirrin.png", + "name": "Txirrin", + "alias": "txirrin", + "theme": { + "primary": "#FB7502" + }, + "hidden": false, + "profile": { + "address": "0xd47f7198bf335bfe66dD29C0f3EeEf0cFE9D05D8", + "chain_id": 100 + }, + "description": "A community for Txirrin", + "primary_token": { + "address": "0x6c6611244547a6E9AaCfBA8744115ca1076756fc", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/txirrin" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0xc2132D05D31c914a87C6611C10748AEb04B58e8F": { + "name": "(PoS) Tether USD", + "symbol": "USDT", + "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x9a81Bd50D56485Cc863Ecb169812c7a821996C8c", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "137:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 137, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://www.ethereumbolivia.org", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/boliviapay.png", + "name": "Bolivia Pay", + "alias": "boliviapay", + "theme": { + "primary": "#009393" + }, + "profile": { + "address": "0x898C2737f2Cb52622711A89D85A1D5E0B881BDeA", + "chain_id": 137 + }, + "description": "A community for Ethereum Bolivia.", + "primary_token": { + "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/boliviapay" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "100:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://100.engine.citizenwallet.xyz", + "ws_url": "wss://100.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "100:0xa555d5344f6fb6c65da19e403cb4c1ec4a1a5ee3": { + "name": "Breadchain Community Token", + "symbol": "BREAD", + "address": "0xa555d5344f6fb6c65da19e403cb4c1ec4a1a5ee3", + "chain_id": 100, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://topup.citizenspring.earth/bread", + "icon": "https://bread.citizenwallet.xyz/uploads/logo.svg", + "name": "Top Up", + "action": "topup" + }, + { + "url": "https://marketplace.citizenwallet.xyz/bread", + "icon": "https://bread.citizenwallet.xyz/uploads/logo.svg", + "name": "Market", + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0x5987e57e85014B5A56C880313580346c20a5d1c1", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "100:0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9": { + "chain_id": 100, + "paymaster_type": "cw", + "paymaster_address": "0xbE2Cb3358aa14621134e923B68b8429315368E32", + "entrypoint_address": "0xcA0a75EF803a364C83c5EAE7Eb889aE7419c9dF2", + "account_factory_address": "0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://breadchain.xyz/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/bread.svg", + "name": "Breadchain Community Token", + "alias": "bread", + "profile": { + "address": "0x6b3a1f4277391526413F583c23D5B9EF4d2fE986", + "chain_id": 100 + }, + "description": "BREAD is a digital community token and solidarity primitive developed by Breadchain Cooperative that generates yield for post-capitalist organizations", + "primary_token": { + "address": "0xa555d5344f6fb6c65da19e403cb4c1ec4a1a5ee3", + "chain_id": 100 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/bread" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "100:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://100.engine.citizenwallet.xyz", + "ws_url": "wss://100.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "100:0x3d36ddFfa4666Ef12a176CaA8C3e67C1047bC007": { + "name": "Labor Hour Token", + "symbol": "HOUR", + "address": "0x3d36ddFfa4666Ef12a176CaA8C3e67C1047bC007", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 4, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0xa7fa16C933f51d8623f39FA0dF34D3065B99Bd1c", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://breadchain.xyz/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/laborhour.png", + "name": "Labor Hour Token", + "alias": "laborhour", + "theme": { + "primary": "#E52D2D" + }, + "profile": { + "address": "0x673601Eb36820bC9718214AC041E96f79383351B", + "chain_id": 100 + }, + "description": "Labor Hour Token aims to reward contributors for hours of labor, particularly targeting non-blockchain native users", + "primary_token": { + "address": "0x3d36ddFfa4666Ef12a176CaA8C3e67C1047bC007", + "chain_id": 100 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://config.internal.citizenwallet.xyz/v4/laborhour.citizenwallet.xyz.json" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "8453:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 8453, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "8453": { + "id": 8453, + "node": { + "url": "https://8453.engine.citizenwallet.xyz", + "ws_url": "wss://8453.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "8453:0x3595ca37596d5895b70efab592ac315d5b9809b2": { + "name": "Azos Stablecoin", + "symbol": "AZUSD", + "address": "0x3595ca37596d5895b70efab592ac315d5b9809b2", + "chain_id": 8453, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "8453:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 8453, + "paymaster_type": "cw-safe", + "paymaster_address": "0x02cd43b3d7a946dCaa8dF12ac0A6Cd50aF9cDd64", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "8453:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 8453, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0x0c2e78DB6FaF8D4d68984A830339764AD9f800D4" + } + }, + "community": { + "url": "https://rooted.finance/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/rooted.png", + "name": "Rooted.Finance", + "alias": "rooted", + "theme": { + "primary": "#ff4c02" + }, + "profile": { + "address": "0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451", + "chain_id": 8453 + }, + "description": "Rooted in your values.", + "primary_token": { + "address": "0x3595ca37596d5895b70efab592ac315d5b9809b2", + "chain_id": 8453 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 8453 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 8453 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 8453 + } + }, + "config_location": "https://my.citizenwallet.xyz/communities/rooted" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "cards": { + "42220:0xc0F9e0907C8de79fd5902b61e463dFEdc5dc8570": { + "type": "classic", + "address": "0xc0F9e0907C8de79fd5902b61e463dFEdc5dc8570", + "chain_id": 42220 + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x65DD32834927de9E57E72a3E2130a19f81C6371D": { + "name": "Commons Hub Token", + "symbol": "CHT", + "address": "0x65DD32834927de9E57E72a3E2130a19f81C6371D", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/wallet.commonshub.brussels", + "icon": "https://marketplace.citizenwallet.xyz/marketplace.svg", + "name": "Market", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x4E127A1DAa66568B4a91E8c5615120a6Ea5442E3", + "entrypoint_address": "0xb7608dDA592d319687C89c4479e320b5a7740117", + "account_factory_address": "0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x4860C0f127500F0cbF4a5Bd797cBb5aA50Eb0FbA", + "entrypoint_address": "0xb7608dDA592d319687C89c4479e320b5a7740117", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://commonshub.brussels", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/chb.png", + "name": "Commons Hub Brussels", + "alias": "wallet.commonshub.brussels", + "theme": { + "primary": "#ff4c02" + }, + "profile": { + "address": "0xc06bE1BbbeEAF2f34F3d5b76069D2560aee184Ae", + "chain_id": 42220 + }, + "description": "Community Token for the Commons Hub Brussels community", + "custom_domain": "wallet.commonshub.brussels", + "primary_token": { + "address": "0x65DD32834927de9E57E72a3E2130a19f81C6371D", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.commonshub.brussels" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "cards": { + "42220:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220, + "instance_id": "cw-seldesalm" + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x83DfEB42347a7Ce46F1497F307a5c156D1f19CB2": { + "name": "Myrtille", + "symbol": "MYRT", + "address": "0x83DfEB42347a7Ce46F1497F307a5c156D1f19CB2", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://citizenwallet.xyz/community-currency-documentation/sel-de-salm", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/myrt.png", + "name": "Informations Générales", + "launch_mode": "webview" + }, + { + "url": "https://marketplace.citizenwallet.xyz/seldesalm", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/myrt.png", + "name": "Échanges", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xd07412020dA5054c3b49f47Ca61224637F1703af", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz/community-currency-documentation/sel-de-salm", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/myrt.png", + "name": "Sel de Salm", + "alias": "seldesalm", + "theme": { + "primary": "#6B5CA4" + }, + "profile": { + "address": "0x4083724953cC1cC13e76b436149B2b1e1a3E5970", + "chain_id": 42220 + }, + "description": "La communauté de Sel de Salm", + "primary_token": { + "address": "0x83DfEB42347a7Ce46F1497F307a5c156D1f19CB2", + "chain_id": 42220 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/seldesalm" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://engine.my.techi.be", + "ws_url": "wss://engine.my.techi.be" + } + } + }, + "tokens": { + "100:0x01D0E7117510b371Ac38f52Cc6689ff8875280FA": { + "name": "TECHI", + "symbol": "TECHI", + "address": "0x01D0E7117510b371Ac38f52Cc6689ff8875280FA", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0x68c5a20f233264DB124a3c95a200bbD20b3b9762", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://my.techi.be", + "logo": "https://my.techi.be/assets/token.svg", + "name": "TECHI", + "alias": "my.techi.be", + "theme": { + "primary": "#617FF8" + }, + "hidden": false, + "profile": { + "address": "0x80C141861607b8FEfD53C9E71a9c7D2D3e2e76dc", + "chain_id": 100 + }, + "description": "A community for TECHI users", + "primary_token": { + "address": "0x01D0E7117510b371Ac38f52Cc6689ff8875280FA", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/my.techi.be" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e": { + "name": "Regens Unite Token", + "symbol": "RGN", + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x250711045d58b6310f0635C7D110BFe663cE1da5", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "137:0x9406Cc6185a346906296840746125a0E44976454": { + "chain_id": 137, + "paymaster_type": "payg", + "paymaster_address": "0x250711045d58b6310f0635C7D110BFe663cE1da5", + "entrypoint_address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "gas_extra_percentage": 50, + "account_factory_address": "0x9406Cc6185a346906296840746125a0E44976454" + } + }, + "community": { + "url": "https://www.regensunite.earth/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/rgn.svg", + "name": "Regens Unite", + "alias": "wallet.regensunite.earth", + "hidden": true, + "profile": { + "address": "0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9", + "chain_id": 137 + }, + "description": "A community currency for the Regens Unite community.", + "custom_domain": "wallet.regensunite.earth", + "primary_token": { + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.regensunite.earth" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1": { + "name": "Gratitude Token", + "symbol": "GT", + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220, + "decimals": 0, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8", + "entrypoint_address": "0x985ec7d08D9d15Ea79876E35FAdEFD58A627187E", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8", + "entrypoint_address": "0x985ec7d08D9d15Ea79876E35FAdEFD58A627187E", + "account_factory_address": "0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD" + } + }, + "community": { + "url": "https://citizenwallet.xyz/gratitude", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/gt.svg", + "name": "Gratitude Token", + "alias": "gt.celo", + "theme": { + "primary": "#a256ff" + }, + "hidden": true, + "profile": { + "address": "0xEEc0F3257369c6bCD2Fd8755CbEf8A95b12Bc4c9", + "chain_id": 42220 + }, + "description": "Express your gratitude towards someone by sending them a token.", + "custom_domain": null, + "primary_token": { + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/gt.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73": { + "name": "Celo Euro", + "symbol": "cEUR", + "address": "0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73", + "chain_id": 42220, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xedbEA8c0F25B34510149EaD4f72867B0d3D2264F", + "entrypoint_address": "0xc3142BCBA2285d0a48A38e7Ea9Cbf28a12B235bB", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0xedbEA8c0F25B34510149EaD4f72867B0d3D2264F", + "entrypoint_address": "0xc3142BCBA2285d0a48A38e7Ea9Cbf28a12B235bB", + "account_factory_address": "0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098" + } + }, + "community": { + "url": "https://celo.org/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/ceur.svg", + "name": "Celo Euro", + "alias": "ceur.celo", + "theme": { + "primary": "#a256ff" + }, + "hidden": true, + "profile": { + "address": "0x0334C579E61aF6922D5deFEF02A361FBb2D6f406", + "chain_id": 42220 + }, + "description": "Celo Euro is a stablecoin for the Celo Community.", + "primary_token": { + "address": "0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/ceur.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x18ec0A6E18E5bc3784fDd3a3634b31245ab704F6": { + "name": "EUR emoney", + "symbol": "EURe", + "address": "0x18ec0A6E18E5bc3784fDd3a3634b31245ab704F6", + "chain_id": 137, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0xB2cb6b75C2357Ca94dBdF58897E468E45fAC83Ec", + "entrypoint_address": "0x2027Bde7C276D5F128587E3107c68A488ee31c72", + "gas_extra_percentage": 50, + "account_factory_address": "0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0xB2cb6b75C2357Ca94dBdF58897E468E45fAC83Ec", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://monerium.com/tokens/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/eure.svg", + "name": "EUR e-money", + "alias": "eure.polygon", + "hidden": true, + "profile": { + "address": "0xF5F7317EDb8E88CaE09071B0C4F0fd6EA20B21f9", + "chain_id": 137 + }, + "description": "Token by Monerium EMI, a regulated entity, licensed in the EEA.", + "primary_token": { + "address": "0x18ec0A6E18E5bc3784fDd3a3634b31245ab704F6", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/eure.polygon" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174": { + "name": "USD Coin", + "symbol": "USDC", + "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x270758454C012A1f51428b68aE473D728CCdFe88": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0xB5D1C0167E6325466E2918e9fda8cc41384C0291", + "entrypoint_address": "0x466AA6ed2B7Bb829841F5aAEA9e82B840eC0feF9", + "gas_extra_percentage": 50, + "account_factory_address": "0x270758454C012A1f51428b68aE473D728CCdFe88" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0xB5D1C0167E6325466E2918e9fda8cc41384C0291", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://en.wikipedia.org/wiki/USD_Coin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/usdc.svg", + "name": "USDC on Polygon", + "alias": "app", + "theme": { + "primary": "#0052ff" + }, + "hidden": true, + "profile": { + "address": "0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7", + "chain_id": 137 + }, + "description": "The community of people using USDC on Polygon.", + "primary_token": { + "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/app" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://basescan.org", + "name": "Base Explorer" + }, + "chains": { + "8453": { + "id": 8453, + "node": { + "url": "https://8453.engine.citizenwallet.xyz", + "ws_url": "wss://8453.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": { + "name": "USD Coin", + "symbol": "USDC", + "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + "chain_id": 8453, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "8453:0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99": { + "chain_id": 8453, + "paymaster_type": "cw", + "paymaster_address": "0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7", + "entrypoint_address": "0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9", + "gas_extra_percentage": 50, + "account_factory_address": "0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99" + }, + "8453:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 8453, + "paymaster_type": "cw-safe", + "paymaster_address": "0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://en.wikipedia.org/wiki/USD_Coin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/usdc.svg", + "name": "USDC on Base", + "alias": "usdc.base", + "theme": { + "primary": "#0052ff" + }, + "hidden": true, + "profile": { + "address": "0x51Ef5Add405CCF63c206A80AF8c2B3cEE0282830", + "chain_id": 8453 + }, + "description": "The community of people using USDC on Base.", + "primary_token": { + "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + "chain_id": 8453 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 8453 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/usdc.base" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://basescan.org", + "name": "Base Explorer" + }, + "chains": { + "8453": { + "id": 8453, + "node": { + "url": "https://8453.engine.citizenwallet.xyz", + "ws_url": "wss://8453.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "8453:0x845598Da418890a674cbaBA26b70807aF0c61dFE": { + "name": "OAK Community Currency", + "symbol": "OAK", + "address": "0x845598Da418890a674cbaBA26b70807aF0c61dFE", + "chain_id": 8453, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "8453:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 8453, + "paymaster_type": "cw-safe", + "paymaster_address": "0x123", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "8453:0x9406Cc6185a346906296840746125a0E44976454": { + "chain_id": 8453, + "paymaster_type": "payg", + "paymaster_address": "0x123", + "entrypoint_address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "account_factory_address": "0x9406Cc6185a346906296840746125a0E44976454" + } + }, + "community": { + "url": "https://www.oak.community/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/oak.svg", + "name": "OAK Community", + "alias": "wallet.oak.community", + "hidden": true, + "profile": { + "address": "0xFE213c74e25505B232CE4C7f89647408bE6f71d2", + "chain_id": 8453 + }, + "description": "A community currency for the city of Oakland.", + "custom_domain": "wallet.oak.community", + "primary_token": { + "address": "0x845598Da418890a674cbaBA26b70807aF0c61dFE", + "chain_id": 8453 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 8453 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.oak.community" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798": { + "name": "Stable Coin", + "symbol": "SBC", + "address": "0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798", + "chain_id": 137, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0x123", + "entrypoint_address": "0xe84423Ba1A3f3535B09237245e22dBda5E27eB88", + "account_factory_address": "0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x123", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://brale.xyz/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/sbc.svg", + "name": "Stable Coin", + "alias": "sbc.polygon", + "hidden": true, + "profile": { + "address": "0xcA0a75EF803a364C83c5EAE7Eb889aE7419c9dF2", + "chain_id": 137 + }, + "description": "SBC is a digital dollar stablecoin issued by Brale", + "primary_token": { + "address": "0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/sbc.polygon" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x5491a3d35F148a44F0af4D718B9636A6e55eBc2D": { + "name": "Zinne.brussels Token", + "symbol": "ZINNE", + "address": "0x5491a3d35F148a44F0af4D718B9636A6e55eBc2D", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x11af2639817692D2b805BcE0e1e405E530B20006": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0xBb796D122Ec1aBDeD081D50B06a072f981c7E62b", + "entrypoint_address": "0xF5507B3042f1C63625D856a2ABFF046243A5D74e", + "account_factory_address": "0x11af2639817692D2b805BcE0e1e405E530B20006" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0xBb796D122Ec1aBDeD081D50B06a072f981c7E62b", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://zinne.brussels", + "logo": "https://citizenwallet.xyz/zinne/zinne-coin.svg", + "name": "Zinne.brussels", + "alias": "zinne", + "hidden": true, + "profile": { + "address": "0x23DB3D3Da510e60aF40902A04850E1F3a744905c", + "chain_id": 137 + }, + "description": "A community currency for the city of Brussels", + "primary_token": { + "address": "0x5491a3d35F148a44F0af4D718B9636A6e55eBc2D", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/zinne" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x186DaBD027e228C988777907465807FDab270894": { + "name": "Regen Hour", + "symbol": "rHour", + "address": "0x186DaBD027e228C988777907465807FDab270894", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/timebank.regensunite.earth", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/rgn.svg", + "name": "Market", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x39b77d77f7677997871b304094a05295eb71e240": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0xe45858bf63176595c2920822581917c7C705a12f", + "entrypoint_address": "0x41176F0C9b8f795Cb99e2DD5Db16017978eeFa4d", + "account_factory_address": "0x39b77d77f7677997871b304094a05295eb71e240" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xe45858bf63176595c2920822581917c7C705a12f", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://regensunite.earth", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/rgn.svg", + "name": "Regens Unite Time Bank", + "alias": "timebank.regensunite.earth", + "hidden": true, + "profile": { + "address": "0x605A827DF8C405D16Ec70AAb8d9a47D21db45c09", + "chain_id": 42220 + }, + "description": "Make time to regen", + "primary_token": { + "address": "0x186DaBD027e228C988777907465807FDab270894", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/timebank.regensunite.earth" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x230542eda83346929e4E54f4a98e1ca1A4BFc0c3": { + "name": "MOOS Token", + "symbol": "MOOS", + "address": "0x230542eda83346929e4E54f4a98e1ca1A4BFc0c3", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/moos", + "icon": "https://moos.citizenwallet.xyz/wallet-config/_images/moos.svg", + "name": "Market", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x671f0662de72268d0f3966Fb62dFc6ee6389e244": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x55E519bfD63c7152D9F7B88Acd712A37F0BEC482", + "entrypoint_address": "0x45a8e6AaDCc48D1Ce19eCbE07Ccd3a536EF712ed", + "account_factory_address": "0x671f0662de72268d0f3966Fb62dFc6ee6389e244" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x55E519bfD63c7152D9F7B88Acd712A37F0BEC482", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://www.moos.garden/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/moos.svg", + "name": "MOOS Token", + "alias": "moos", + "hidden": true, + "profile": { + "address": "0x2e4542Be47408d05F41703386eFaf4338Ee1D341", + "chain_id": 42220 + }, + "description": "A community currency for MOOS.", + "primary_token": { + "address": "0x230542eda83346929e4E54f4a98e1ca1A4BFc0c3", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/moos" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x5Cdbc862BF4E20D98456D4c41D4A5239aDd496d3": { + "name": "Bonne Heure", + "symbol": "BHR", + "address": "0x5Cdbc862BF4E20D98456D4c41D4A5239aDd496d3", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/selcoupdepouce", + "icon": "https://marketplace.citizenwallet.xyz/marketplace.svg", + "name": "Market", + "signature": true, + "launch_mode": "browser" + } + ], + "version": 5, + "accounts": { + "42220:0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x635032605337aB36A46D767905108e67EE687a72", + "entrypoint_address": "0xA90904F33df36899d810d040b8d5b3b77265Bb05", + "account_factory_address": "0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x635032605337aB36A46D767905108e67EE687a72", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://selcoupdepouce.be", + "logo": "https://topup.citizenwallet.xyz/communities/selcoupdepouce/sel-coin.svg", + "name": "Bonne Heure", + "alias": "selcoupdepouce", + "hidden": true, + "profile": { + "address": "0xfB8F1e7ED42599638B3c509679E2F43937002C56", + "chain_id": 42220 + }, + "description": "Système d'Échange Local de Villers-la-Ville", + "primary_token": { + "address": "0x5Cdbc862BF4E20D98456D4c41D4A5239aDd496d3", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/selcoupdepouce" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x12e26FAED228c425BceA8a8dd7658a9CeD944dd9": { + "name": "CI token", + "symbol": "CIT", + "address": "0x12e26FAED228c425BceA8a8dd7658a9CeD944dd9", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x452F7ff3e55fe29f481841985dE7f4939FD645fa", + "entrypoint_address": "0xB8d9412f3A91A00ca762B5c35cd0863E9b716D68", + "account_factory_address": "0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x452F7ff3e55fe29f481841985dE7f4939FD645fa", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://citizenwallet.xyz/cit", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/cit.celo.svg", + "name": "CI token", + "alias": "cit.celo", + "hidden": true, + "profile": { + "address": "0x4cB296BEc9FAd0B5e1E4FF1A2F307B425724AC82", + "chain_id": 42220 + }, + "description": "Monnaie locale du Cercle Informatique de l’ULB", + "primary_token": { + "address": "0x12e26FAED228c425BceA8a8dd7658a9CeD944dd9", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/cit.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "cards": { + "42220:0xA3E1446E332a098A1f3b0555c5d149b4784A095F": { + "type": "classic", + "address": "0xA3E1446E332a098A1f3b0555c5d149b4784A095F", + "chain_id": 42220 + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451": { + "name": "Wolu", + "symbol": "WOLU", + "address": "0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xF2EFEC3cBFaDE0bB6108620cbF7Cc608d27DCF3c", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0x8474153A00C959f2cB64852949954DBC68415Bb3": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0xF2EFEC3cBFaDE0bB6108620cbF7Cc608d27DCF3c", + "entrypoint_address": "0x0F805BC1ED718FB9C7C18439cB11E1C17C6538C4", + "account_factory_address": "0x8474153A00C959f2cB64852949954DBC68415Bb3" + } + }, + "community": { + "url": "https://wolugo.be", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/wolugo.svg", + "name": "Wolugo", + "alias": "wallet.wolugo.be", + "theme": { + "primary": "#81e2c1" + }, + "hidden": true, + "profile": { + "address": "0x07e7b95B35866302b3A089feF4CFA3061061a51d", + "chain_id": 42220 + }, + "description": "A community for the Woluwe-Saint-Pierre civic engagement platform", + "card_factory": { + "address": "0xA3E1446E332a098A1f3b0555c5d149b4784A095F", + "chain_id": 42220 + }, + "custom_domain": "wallet.wolugo.be", + "primary_token": { + "address": "0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.wolugo.be" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0xc53Cb35591959cA62471dA9fF6AC16629A89874a": { + "name": "Woluwe Test Coin", + "symbol": "WTC", + "address": "0xc53Cb35591959cA62471dA9fF6AC16629A89874a", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x3fefC19674f3F6E43B1dFf1861E07c303B9eAAc9", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xE79E19594A749330036280c685E2719d58d99052": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x3fefC19674f3F6E43B1dFf1861E07c303B9eAAc9", + "entrypoint_address": "0x1EaF6B6A6967608aF6c77224f087b042095891EB", + "account_factory_address": "0xE79E19594A749330036280c685E2719d58d99052" + } + }, + "community": { + "url": "https://wollet-v2.citizenwallet.net/token", + "logo": "https://wtc.celo.citizenwallet.xyz/wallet-config/_images/wtc.celo.svg", + "name": "Woluwe Test", + "alias": "wtc.celo", + "hidden": true, + "profile": { + "address": "0xB99a7B1574f051020EB4cb2fce5d48EE07592AfF", + "chain_id": 42220 + }, + "description": "Local currency for the Woluwe Test community.", + "primary_token": { + "address": "0xc53Cb35591959cA62471dA9fF6AC16629A89874a", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wtc.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://sepolia.basescan.org", + "name": "Base Sepolia Explorer" + }, + "chains": { + "84532": { + "id": 84532, + "node": { + "url": "https://84532.engine.citizenwallet.xyz", + "ws_url": "wss://84532.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "84532:0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e": { + "name": "ETHGlobal London Token", + "symbol": "ETHLDN", + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 84532, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "84532:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 84532, + "paymaster_type": "cw-safe", + "paymaster_address": "0x389182aCCeE26D953d5188BF4b92c49339DcC9FC", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "84532:0xc1654087C580f868F08E34cd1c01eDB1d3673b82": { + "chain_id": 84532, + "paymaster_type": "cw", + "paymaster_address": "0x389182aCCeE26D953d5188BF4b92c49339DcC9FC", + "entrypoint_address": "0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE", + "account_factory_address": "0xc1654087C580f868F08E34cd1c01eDB1d3673b82" + } + }, + "community": { + "url": "https://en.wikipedia.org/wiki/USD_Coin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/testnet-ethldn.svg", + "name": "ETHGlobal London Token", + "alias": "testnet-ethldn", + "hidden": true, + "profile": { + "address": "0x0785D720279f42326846D5396b5F44b97d0BfECd", + "chain_id": 84532 + }, + "description": "The community of people using ETHLDN on Base.", + "primary_token": { + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 84532 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 84532 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/testnet-ethldn" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x3C960E72BBbD837293e75080E1d0Fee6a4640357": { + "name": "Celo Community Point", + "symbol": "CeloC", + "address": "0x3C960E72BBbD837293e75080E1d0Fee6a4640357", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x7f4011845Ea914b6cefc60629e1e00600c972c75", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x7f4011845Ea914b6cefc60629e1e00600c972c75", + "entrypoint_address": "0x66fE9c22CcA49B257dd4F00508AC90198d99Bf27", + "account_factory_address": "0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA" + } + }, + "community": { + "url": "https://citizenwallet.xyz", + "logo": "https://celo-c.citizenwallet.xyz/uploads/logo.svg", + "name": "Celo Community Point", + "alias": "celo-c.citizenwallet.xyz", + "hidden": true, + "profile": { + "address": "0x14004E13907282cFaD05f742022E56926eE92dAd", + "chain_id": 42220 + }, + "description": "This is a community for the Celo Point", + "primary_token": { + "address": "0x3C960E72BBbD837293e75080E1d0Fee6a4640357", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/celo-c.citizenwallet.xyz" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x56744910f7dEcD48c1a7FA61B4C317b15E99F156": { + "name": "KFMEDIA℠ Pathways for LATAM™", + "symbol": "KFMPFL", + "address": "0x56744910f7dEcD48c1a7FA61B4C317b15E99F156", + "chain_id": 42220, + "decimals": 0, + "standard": "erc1155" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x02BDA8370d9497A5C808B2db237cfaA8f0733F36", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://kingfishersmedia.io", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/kfmpfl.png", + "name": "KFMEDIA℠", + "alias": "wallet.kingfishersmedia.io", + "theme": { + "primary": "#88292c" + }, + "profile": { + "address": "0x5f6FEb03ad8EfeCdD2a837FAA1a29DEA2bAcfd55", + "chain_id": 42220 + }, + "description": "Certified Education Organization. Solving systemic educational disparity using Web3 solutions, removing barriers of entry for underdeveloped economies.", + "custom_domain": "wallet.kingfishersmedia.io", + "primary_token": { + "address": "0x56744910f7dEcD48c1a7FA61B4C317b15E99F156", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.kingfishersmedia.io" + } +] diff --git a/assets/config/v5/communities.test.json b/assets/config/v5/communities.test.json new file mode 100644 index 00000000..396deeb6 --- /dev/null +++ b/assets/config/v5/communities.test.json @@ -0,0 +1,2444 @@ +[ + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "cards": { + "137:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 137, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x0D9B0790E97e3426C161580dF4Ee853E4A7C4607": { + "name": "Citizen Wallet", + "symbol": "CTZN", + "address": "0x0D9B0790E97e3426C161580dF4Ee853E4A7C4607", + "chain_id": 137, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://citizenwallet.xyz/pay-with-ctzn", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/ctzn.svg", + "name": "About", + "launch_mode": "browser" + }, + { + "url": "https://my.citizenwallet.xyz/onramp", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/ctzn.svg", + "name": "Top Up", + "action": "topup", + "signature": true + } + ], + "version": 5, + "accounts": { + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x3A3E25871c5C6C84D5f397829FF316a37F7FD596", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "137:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 137, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/ctzn.svg", + "name": "Citizen Wallet (CTZN)", + "alias": "ctzn", + "theme": { + "primary": "#9563D3" + }, + "profile": { + "address": "0x8dA817724Eb6A2aA47c0F8d8b8A98b9B3C2Ddb68", + "chain_id": 137 + }, + "description": "The token powering the Citizen Wallet economy.", + "primary_token": { + "address": "0x0D9B0790E97e3426C161580dF4Ee853E4A7C4607", + "chain_id": 137 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/ctzn" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "100:0x1EaF6B6A6967608aF6c77224f087b042095891EB": { + "type": "classic", + "address": "0x1EaF6B6A6967608aF6c77224f087b042095891EB", + "chain_id": 100 + }, + "100:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100, + "instance_id": "brussels-pay" + } + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://engine.pay.brussels", + "ws_url": "wss://engine.pay.brussels" + } + } + }, + "tokens": { + "100:0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1": { + "name": "pay.brussels", + "symbol": "EURb", + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://checkout.pay.brussels/topup", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/wallet.pay.brussels.png", + "name": "Top Up", + "action": "topup", + "signature": true + } + ], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0xE69C843898E21C0E95eA7DD310cD850AAc0aB897", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "100:0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE": { + "chain_id": 100, + "paymaster_type": "cw", + "paymaster_address": "0xcA1B9EC1117340818C1c1fdd1B48Ea79E57C140F", + "entrypoint_address": "0xAAEb9DC18aDadae9b3aE7ec2b47842565A81113f", + "account_factory_address": "0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://pay.brussels", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/wallet.pay.brussels.png", + "name": "Brussels Pay", + "alias": "wallet.pay.brussels", + "theme": { + "primary": "#4a90e2" + }, + "hidden": false, + "profile": { + "address": "0x56Cc38bDa01bE6eC6D854513C995f6621Ee71229", + "chain_id": 100 + }, + "description": "A community for the city of Brussels", + "custom_domain": "wallet.pay.brussels", + "primary_token": { + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 100 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.pay.brussels" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "cards": { + "42220:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1": { + "name": "Gratitude Token", + "symbol": "GT", + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220, + "decimals": 0, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xF05ba2641b31AF70c2678e3324eD8b9C53093FbE", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8", + "entrypoint_address": "0x985ec7d08D9d15Ea79876E35FAdEFD58A627187E", + "account_factory_address": "0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz/gratitude", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/gt.svg", + "name": "Gratitude Token", + "alias": "gratitude", + "theme": { + "primary": "#4EC19D" + }, + "profile": { + "address": "0xEEc0F3257369c6bCD2Fd8755CbEf8A95b12Bc4c9", + "chain_id": 42220 + }, + "description": "Express your gratitude towards someone by sending them a token of gratitude.", + "primary_token": { + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/gratitude" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "cards": { + "80094:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 80094, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "80094": { + "id": 80094, + "node": { + "url": "https://80094.engine.citizenwallet.xyz", + "ws_url": "wss://80094.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "80094:0x881cad4f885c6701d8481c0ed347f6d35444ea7e": { + "name": "SFLUV V1.1", + "symbol": "SFLUV", + "address": "0x881cad4f885c6701d8481c0ed347f6d35444ea7e", + "chain_id": 80094, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://app.sfluv.org", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "About", + "hidden": true, + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "80094:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 80094, + "paymaster_type": "cw-safe", + "paymaster_address": "0x9A5be02B65f9Aa00060cB8c951dAFaBAB9B860cd", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "80094:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 80094, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://sfluv.org", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "SFLUV Community", + "alias": "wallet.berachain.sfluv.org", + "theme": { + "primary": "#eb6c6c" + }, + "profile": { + "address": "0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99", + "chain_id": 80094 + }, + "description": "A community currency for the city of San Francisco.", + "custom_domain": "wallet.sfluv.org", + "primary_token": { + "address": "0x881cad4f885c6701d8481c0ed347f6d35444ea7e", + "chain_id": 80094 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 80094 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 80094 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 80094 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.berachain.sfluv.org" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x58a2993A618Afee681DE23dECBCF535A58A080BA": { + "name": "SFLUV V1.1", + "symbol": "SFLUV", + "address": "0x58a2993A618Afee681DE23dECBCF535A58A080BA", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://app.sfluv.org", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "About", + "hidden": true, + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "137:0x5e987a6c4bb4239d498E78c34e986acf29c81E8e": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0x7FC98D0a2bd7f766bAca37388eB0F6Db37666B33", + "entrypoint_address": "0x2d01C5E40Aa6a8478eD0FFbF2784EBb9bf67C46A", + "account_factory_address": "0x5e987a6c4bb4239d498E78c34e986acf29c81E8e" + } + }, + "sessions": { + "137:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 137, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://sfluv.org", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/sfluv.svg", + "name": "SFLUV Community (Polygon)", + "alias": "wallet.sfluv.org", + "theme": { + "primary": "#eb6c6c" + }, + "profile": { + "address": "0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99", + "chain_id": 137 + }, + "description": "A community currency for the city of San Francisco.", + "custom_domain": "wallet.polygon.sfluv.org", + "primary_token": { + "address": "0x58a2993A618Afee681DE23dECBCF535A58A080BA", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x5e987a6c4bb4239d498E78c34e986acf29c81E8e", + "chain_id": 137 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.sfluv.org" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://100.engine.citizenwallet.xyz", + "ws_url": "wss://100.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "100:0x6c6611244547a6E9AaCfBA8744115ca1076756fc": { + "name": "Txirrin", + "symbol": "TXI", + "address": "0x6c6611244547a6E9AaCfBA8744115ca1076756fc", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0x33500E7Eb3452421e56c2f4117530B1C4C85E0A5", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz/txirrin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/txirrin.png", + "name": "Txirrin", + "alias": "txirrin", + "theme": { + "primary": "#FB7502" + }, + "hidden": false, + "profile": { + "address": "0xd47f7198bf335bfe66dD29C0f3EeEf0cFE9D05D8", + "chain_id": 100 + }, + "description": "A community for Txirrin", + "primary_token": { + "address": "0x6c6611244547a6E9AaCfBA8744115ca1076756fc", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/txirrin" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0xc2132D05D31c914a87C6611C10748AEb04B58e8F": { + "name": "(PoS) Tether USD", + "symbol": "USDT", + "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x9a81Bd50D56485Cc863Ecb169812c7a821996C8c", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "137:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 137, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://www.ethereumbolivia.org", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/boliviapay.png", + "name": "Bolivia Pay", + "alias": "boliviapay", + "theme": { + "primary": "#009393" + }, + "profile": { + "address": "0x898C2737f2Cb52622711A89D85A1D5E0B881BDeA", + "chain_id": 137 + }, + "description": "A community for Ethereum Bolivia.", + "primary_token": { + "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/boliviapay" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "100:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://100.engine.citizenwallet.xyz", + "ws_url": "wss://100.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "100:0xa555d5344f6fb6c65da19e403cb4c1ec4a1a5ee3": { + "name": "Breadchain Community Token", + "symbol": "BREAD", + "address": "0xa555d5344f6fb6c65da19e403cb4c1ec4a1a5ee3", + "chain_id": 100, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://topup.citizenspring.earth/bread", + "icon": "https://bread.citizenwallet.xyz/uploads/logo.svg", + "name": "Top Up", + "action": "topup" + }, + { + "url": "https://marketplace.citizenwallet.xyz/bread", + "icon": "https://bread.citizenwallet.xyz/uploads/logo.svg", + "name": "Market", + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0x5987e57e85014B5A56C880313580346c20a5d1c1", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "100:0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9": { + "chain_id": 100, + "paymaster_type": "cw", + "paymaster_address": "0xbE2Cb3358aa14621134e923B68b8429315368E32", + "entrypoint_address": "0xcA0a75EF803a364C83c5EAE7Eb889aE7419c9dF2", + "account_factory_address": "0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://breadchain.xyz/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/bread.svg", + "name": "Breadchain Community Token", + "alias": "bread", + "profile": { + "address": "0x6b3a1f4277391526413F583c23D5B9EF4d2fE986", + "chain_id": 100 + }, + "description": "BREAD is a digital community token and solidarity primitive developed by Breadchain Cooperative that generates yield for post-capitalist organizations", + "primary_token": { + "address": "0xa555d5344f6fb6c65da19e403cb4c1ec4a1a5ee3", + "chain_id": 100 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/bread" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "100:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://100.engine.citizenwallet.xyz", + "ws_url": "wss://100.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "100:0x3d36ddFfa4666Ef12a176CaA8C3e67C1047bC007": { + "name": "Labor Hour Token", + "symbol": "HOUR", + "address": "0x3d36ddFfa4666Ef12a176CaA8C3e67C1047bC007", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 4, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0xa7fa16C933f51d8623f39FA0dF34D3065B99Bd1c", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://breadchain.xyz/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/laborhour.png", + "name": "Labor Hour Token", + "alias": "laborhour", + "theme": { + "primary": "#E52D2D" + }, + "profile": { + "address": "0x673601Eb36820bC9718214AC041E96f79383351B", + "chain_id": 100 + }, + "description": "Labor Hour Token aims to reward contributors for hours of labor, particularly targeting non-blockchain native users", + "primary_token": { + "address": "0x3d36ddFfa4666Ef12a176CaA8C3e67C1047bC007", + "chain_id": 100 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://config.internal.citizenwallet.xyz/v4/laborhour.citizenwallet.xyz.json" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "cards": { + "8453:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 8453, + "instance_id": "cw-discord-1" + } + }, + "chains": { + "8453": { + "id": 8453, + "node": { + "url": "https://8453.engine.citizenwallet.xyz", + "ws_url": "wss://8453.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "8453:0x3595ca37596d5895b70efab592ac315d5b9809b2": { + "name": "Azos Stablecoin", + "symbol": "AZUSD", + "address": "0x3595ca37596d5895b70efab592ac315d5b9809b2", + "chain_id": 8453, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "8453:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 8453, + "paymaster_type": "cw-safe", + "paymaster_address": "0x02cd43b3d7a946dCaa8dF12ac0A6Cd50aF9cDd64", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "8453:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 8453, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0x0c2e78DB6FaF8D4d68984A830339764AD9f800D4" + } + }, + "community": { + "url": "https://rooted.finance/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/rooted.png", + "name": "Rooted.Finance", + "alias": "rooted", + "theme": { + "primary": "#ff4c02" + }, + "profile": { + "address": "0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451", + "chain_id": 8453 + }, + "description": "Rooted in your values.", + "primary_token": { + "address": "0x3595ca37596d5895b70efab592ac315d5b9809b2", + "chain_id": 8453 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 8453 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 8453 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 8453 + } + }, + "config_location": "https://my.citizenwallet.xyz/communities/rooted" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "cards": { + "42220:0xc0F9e0907C8de79fd5902b61e463dFEdc5dc8570": { + "type": "classic", + "address": "0xc0F9e0907C8de79fd5902b61e463dFEdc5dc8570", + "chain_id": 42220 + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x65DD32834927de9E57E72a3E2130a19f81C6371D": { + "name": "Commons Hub Token", + "symbol": "CHT", + "address": "0x65DD32834927de9E57E72a3E2130a19f81C6371D", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/wallet.commonshub.brussels", + "icon": "https://marketplace.citizenwallet.xyz/marketplace.svg", + "name": "Market", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x4E127A1DAa66568B4a91E8c5615120a6Ea5442E3", + "entrypoint_address": "0xb7608dDA592d319687C89c4479e320b5a7740117", + "account_factory_address": "0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x4860C0f127500F0cbF4a5Bd797cBb5aA50Eb0FbA", + "entrypoint_address": "0xb7608dDA592d319687C89c4479e320b5a7740117", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://commonshub.brussels", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/chb.png", + "name": "Commons Hub Brussels", + "alias": "wallet.commonshub.brussels", + "theme": { + "primary": "#ff4c02" + }, + "profile": { + "address": "0xc06bE1BbbeEAF2f34F3d5b76069D2560aee184Ae", + "chain_id": 42220 + }, + "description": "Community Token for the Commons Hub Brussels community", + "custom_domain": "wallet.commonshub.brussels", + "primary_token": { + "address": "0x65DD32834927de9E57E72a3E2130a19f81C6371D", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.commonshub.brussels" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "cards": { + "42220:0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28": { + "type": "safe", + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220, + "instance_id": "cw-seldesalm" + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x83DfEB42347a7Ce46F1497F307a5c156D1f19CB2": { + "name": "Myrtille", + "symbol": "MYRT", + "address": "0x83DfEB42347a7Ce46F1497F307a5c156D1f19CB2", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://citizenwallet.xyz/community-currency-documentation/sel-de-salm", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/myrt.png", + "name": "Informations Générales", + "launch_mode": "webview" + }, + { + "url": "https://marketplace.citizenwallet.xyz/seldesalm", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/myrt.png", + "name": "Échanges", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xd07412020dA5054c3b49f47Ca61224637F1703af", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://citizenwallet.xyz/community-currency-documentation/sel-de-salm", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/myrt.png", + "name": "Sel de Salm", + "alias": "seldesalm", + "theme": { + "primary": "#6B5CA4" + }, + "profile": { + "address": "0x4083724953cC1cC13e76b436149B2b1e1a3E5970", + "chain_id": 42220 + }, + "description": "La communauté de Sel de Salm", + "primary_token": { + "address": "0x83DfEB42347a7Ce46F1497F307a5c156D1f19CB2", + "chain_id": 42220 + }, + "primary_card_manager": { + "address": "0xBA861e2DABd8316cf11Ae7CdA101d110CF581f28", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/seldesalm" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://gnosisscan.io", + "name": "Gnosis Explorer" + }, + "chains": { + "100": { + "id": 100, + "node": { + "url": "https://engine.my.techi.be", + "ws_url": "wss://engine.my.techi.be" + } + } + }, + "tokens": { + "100:0x01D0E7117510b371Ac38f52Cc6689ff8875280FA": { + "name": "TECHI", + "symbol": "TECHI", + "address": "0x01D0E7117510b371Ac38f52Cc6689ff8875280FA", + "chain_id": 100, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "100:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 100, + "paymaster_type": "cw-safe", + "paymaster_address": "0x68c5a20f233264DB124a3c95a200bbD20b3b9762", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "100:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 100, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://my.techi.be", + "logo": "https://my.techi.be/assets/token.svg", + "name": "TECHI", + "alias": "my.techi.be", + "theme": { + "primary": "#617FF8" + }, + "hidden": false, + "profile": { + "address": "0x80C141861607b8FEfD53C9E71a9c7D2D3e2e76dc", + "chain_id": 100 + }, + "description": "A community for TECHI users", + "primary_token": { + "address": "0x01D0E7117510b371Ac38f52Cc6689ff8875280FA", + "chain_id": 100 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 100 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 100 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/my.techi.be" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e": { + "name": "Regens Unite Token", + "symbol": "RGN", + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x250711045d58b6310f0635C7D110BFe663cE1da5", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "137:0x9406Cc6185a346906296840746125a0E44976454": { + "chain_id": 137, + "paymaster_type": "payg", + "paymaster_address": "0x250711045d58b6310f0635C7D110BFe663cE1da5", + "entrypoint_address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "gas_extra_percentage": 50, + "account_factory_address": "0x9406Cc6185a346906296840746125a0E44976454" + } + }, + "community": { + "url": "https://www.regensunite.earth/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/rgn.svg", + "name": "Regens Unite", + "alias": "wallet.regensunite.earth", + "hidden": true, + "profile": { + "address": "0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9", + "chain_id": 137 + }, + "description": "A community currency for the Regens Unite community.", + "custom_domain": "wallet.regensunite.earth", + "primary_token": { + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.regensunite.earth" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1": { + "name": "Gratitude Token", + "symbol": "GT", + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220, + "decimals": 0, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8", + "entrypoint_address": "0x985ec7d08D9d15Ea79876E35FAdEFD58A627187E", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8", + "entrypoint_address": "0x985ec7d08D9d15Ea79876E35FAdEFD58A627187E", + "account_factory_address": "0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD" + } + }, + "community": { + "url": "https://citizenwallet.xyz/gratitude", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/gt.svg", + "name": "Gratitude Token", + "alias": "gt.celo", + "theme": { + "primary": "#a256ff" + }, + "hidden": true, + "profile": { + "address": "0xEEc0F3257369c6bCD2Fd8755CbEf8A95b12Bc4c9", + "chain_id": 42220 + }, + "description": "Express your gratitude towards someone by sending them a token.", + "custom_domain": null, + "primary_token": { + "address": "0x5815E61eF72c9E6107b5c5A05FD121F334f7a7f1", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/gt.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73": { + "name": "Celo Euro", + "symbol": "cEUR", + "address": "0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73", + "chain_id": 42220, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xedbEA8c0F25B34510149EaD4f72867B0d3D2264F", + "entrypoint_address": "0xc3142BCBA2285d0a48A38e7Ea9Cbf28a12B235bB", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0xedbEA8c0F25B34510149EaD4f72867B0d3D2264F", + "entrypoint_address": "0xc3142BCBA2285d0a48A38e7Ea9Cbf28a12B235bB", + "account_factory_address": "0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098" + } + }, + "community": { + "url": "https://celo.org/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/ceur.svg", + "name": "Celo Euro", + "alias": "ceur.celo", + "theme": { + "primary": "#a256ff" + }, + "hidden": true, + "profile": { + "address": "0x0334C579E61aF6922D5deFEF02A361FBb2D6f406", + "chain_id": 42220 + }, + "description": "Celo Euro is a stablecoin for the Celo Community.", + "primary_token": { + "address": "0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/ceur.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x18ec0A6E18E5bc3784fDd3a3634b31245ab704F6": { + "name": "EUR emoney", + "symbol": "EURe", + "address": "0x18ec0A6E18E5bc3784fDd3a3634b31245ab704F6", + "chain_id": 137, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0xB2cb6b75C2357Ca94dBdF58897E468E45fAC83Ec", + "entrypoint_address": "0x2027Bde7C276D5F128587E3107c68A488ee31c72", + "gas_extra_percentage": 50, + "account_factory_address": "0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0xB2cb6b75C2357Ca94dBdF58897E468E45fAC83Ec", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://monerium.com/tokens/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/eure.svg", + "name": "EUR e-money", + "alias": "eure.polygon", + "hidden": true, + "profile": { + "address": "0xF5F7317EDb8E88CaE09071B0C4F0fd6EA20B21f9", + "chain_id": 137 + }, + "description": "Token by Monerium EMI, a regulated entity, licensed in the EEA.", + "primary_token": { + "address": "0x18ec0A6E18E5bc3784fDd3a3634b31245ab704F6", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/eure.polygon" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174": { + "name": "USD Coin", + "symbol": "USDC", + "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x270758454C012A1f51428b68aE473D728CCdFe88": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0xB5D1C0167E6325466E2918e9fda8cc41384C0291", + "entrypoint_address": "0x466AA6ed2B7Bb829841F5aAEA9e82B840eC0feF9", + "gas_extra_percentage": 50, + "account_factory_address": "0x270758454C012A1f51428b68aE473D728CCdFe88" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0xB5D1C0167E6325466E2918e9fda8cc41384C0291", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://en.wikipedia.org/wiki/USD_Coin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/usdc.svg", + "name": "USDC on Polygon", + "alias": "app", + "theme": { + "primary": "#0052ff" + }, + "hidden": true, + "profile": { + "address": "0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7", + "chain_id": 137 + }, + "description": "The community of people using USDC on Polygon.", + "primary_token": { + "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/app" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://basescan.org", + "name": "Base Explorer" + }, + "chains": { + "8453": { + "id": 8453, + "node": { + "url": "https://8453.engine.citizenwallet.xyz", + "ws_url": "wss://8453.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": { + "name": "USD Coin", + "symbol": "USDC", + "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + "chain_id": 8453, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "8453:0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99": { + "chain_id": 8453, + "paymaster_type": "cw", + "paymaster_address": "0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7", + "entrypoint_address": "0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9", + "gas_extra_percentage": 50, + "account_factory_address": "0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99" + }, + "8453:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 8453, + "paymaster_type": "cw-safe", + "paymaster_address": "0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://en.wikipedia.org/wiki/USD_Coin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/usdc.svg", + "name": "USDC on Base", + "alias": "usdc.base", + "theme": { + "primary": "#0052ff" + }, + "hidden": true, + "profile": { + "address": "0x51Ef5Add405CCF63c206A80AF8c2B3cEE0282830", + "chain_id": 8453 + }, + "description": "The community of people using USDC on Base.", + "primary_token": { + "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + "chain_id": 8453 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 8453 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/usdc.base" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://basescan.org", + "name": "Base Explorer" + }, + "chains": { + "8453": { + "id": 8453, + "node": { + "url": "https://8453.engine.citizenwallet.xyz", + "ws_url": "wss://8453.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "8453:0x845598Da418890a674cbaBA26b70807aF0c61dFE": { + "name": "OAK Community Currency", + "symbol": "OAK", + "address": "0x845598Da418890a674cbaBA26b70807aF0c61dFE", + "chain_id": 8453, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "8453:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 8453, + "paymaster_type": "cw-safe", + "paymaster_address": "0x123", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "8453:0x9406Cc6185a346906296840746125a0E44976454": { + "chain_id": 8453, + "paymaster_type": "payg", + "paymaster_address": "0x123", + "entrypoint_address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", + "account_factory_address": "0x9406Cc6185a346906296840746125a0E44976454" + } + }, + "community": { + "url": "https://www.oak.community/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/oak.svg", + "name": "OAK Community", + "alias": "wallet.oak.community", + "hidden": true, + "profile": { + "address": "0xFE213c74e25505B232CE4C7f89647408bE6f71d2", + "chain_id": 8453 + }, + "description": "A community currency for the city of Oakland.", + "custom_domain": "wallet.oak.community", + "primary_token": { + "address": "0x845598Da418890a674cbaBA26b70807aF0c61dFE", + "chain_id": 8453 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 8453 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.oak.community" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798": { + "name": "Stable Coin", + "symbol": "SBC", + "address": "0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798", + "chain_id": 137, + "decimals": 18, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0x123", + "entrypoint_address": "0xe84423Ba1A3f3535B09237245e22dBda5E27eB88", + "account_factory_address": "0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0x123", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://brale.xyz/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/sbc.svg", + "name": "Stable Coin", + "alias": "sbc.polygon", + "hidden": true, + "profile": { + "address": "0xcA0a75EF803a364C83c5EAE7Eb889aE7419c9dF2", + "chain_id": 137 + }, + "description": "SBC is a digital dollar stablecoin issued by Brale", + "primary_token": { + "address": "0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/sbc.polygon" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://polygonscan.com", + "name": "Polygon Explorer" + }, + "chains": { + "137": { + "id": 137, + "node": { + "url": "https://137.engine.citizenwallet.xyz", + "ws_url": "wss://137.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "137:0x5491a3d35F148a44F0af4D718B9636A6e55eBc2D": { + "name": "Zinne.brussels Token", + "symbol": "ZINNE", + "address": "0x5491a3d35F148a44F0af4D718B9636A6e55eBc2D", + "chain_id": 137, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [], + "version": 5, + "accounts": { + "137:0x11af2639817692D2b805BcE0e1e405E530B20006": { + "chain_id": 137, + "paymaster_type": "cw", + "paymaster_address": "0xBb796D122Ec1aBDeD081D50B06a072f981c7E62b", + "entrypoint_address": "0xF5507B3042f1C63625D856a2ABFF046243A5D74e", + "account_factory_address": "0x11af2639817692D2b805BcE0e1e405E530B20006" + }, + "137:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 137, + "paymaster_type": "cw-safe", + "paymaster_address": "0xBb796D122Ec1aBDeD081D50B06a072f981c7E62b", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://zinne.brussels", + "logo": "https://citizenwallet.xyz/zinne/zinne-coin.svg", + "name": "Zinne.brussels", + "alias": "zinne", + "hidden": true, + "profile": { + "address": "0x23DB3D3Da510e60aF40902A04850E1F3a744905c", + "chain_id": 137 + }, + "description": "A community currency for the city of Brussels", + "primary_token": { + "address": "0x5491a3d35F148a44F0af4D718B9636A6e55eBc2D", + "chain_id": 137 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 137 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/zinne" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x186DaBD027e228C988777907465807FDab270894": { + "name": "Regen Hour", + "symbol": "rHour", + "address": "0x186DaBD027e228C988777907465807FDab270894", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/timebank.regensunite.earth", + "icon": "https://assets.citizenwallet.xyz/wallet-config/_images/rgn.svg", + "name": "Market", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x39b77d77f7677997871b304094a05295eb71e240": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0xe45858bf63176595c2920822581917c7C705a12f", + "entrypoint_address": "0x41176F0C9b8f795Cb99e2DD5Db16017978eeFa4d", + "account_factory_address": "0x39b77d77f7677997871b304094a05295eb71e240" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xe45858bf63176595c2920822581917c7C705a12f", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://regensunite.earth", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/rgn.svg", + "name": "Regens Unite Time Bank", + "alias": "timebank.regensunite.earth", + "hidden": true, + "profile": { + "address": "0x605A827DF8C405D16Ec70AAb8d9a47D21db45c09", + "chain_id": 42220 + }, + "description": "Make time to regen", + "primary_token": { + "address": "0x186DaBD027e228C988777907465807FDab270894", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/timebank.regensunite.earth" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x230542eda83346929e4E54f4a98e1ca1A4BFc0c3": { + "name": "MOOS Token", + "symbol": "MOOS", + "address": "0x230542eda83346929e4E54f4a98e1ca1A4BFc0c3", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/moos", + "icon": "https://moos.citizenwallet.xyz/wallet-config/_images/moos.svg", + "name": "Market", + "signature": true, + "launch_mode": "webview" + } + ], + "version": 5, + "accounts": { + "42220:0x671f0662de72268d0f3966Fb62dFc6ee6389e244": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x55E519bfD63c7152D9F7B88Acd712A37F0BEC482", + "entrypoint_address": "0x45a8e6AaDCc48D1Ce19eCbE07Ccd3a536EF712ed", + "account_factory_address": "0x671f0662de72268d0f3966Fb62dFc6ee6389e244" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x55E519bfD63c7152D9F7B88Acd712A37F0BEC482", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://www.moos.garden/", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/moos.svg", + "name": "MOOS Token", + "alias": "moos", + "hidden": true, + "profile": { + "address": "0x2e4542Be47408d05F41703386eFaf4338Ee1D341", + "chain_id": 42220 + }, + "description": "A community currency for MOOS.", + "primary_token": { + "address": "0x230542eda83346929e4E54f4a98e1ca1A4BFc0c3", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/moos" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x5Cdbc862BF4E20D98456D4c41D4A5239aDd496d3": { + "name": "Bonne Heure", + "symbol": "BHR", + "address": "0x5Cdbc862BF4E20D98456D4c41D4A5239aDd496d3", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "plugins": [ + { + "url": "https://marketplace.citizenwallet.xyz/selcoupdepouce", + "icon": "https://marketplace.citizenwallet.xyz/marketplace.svg", + "name": "Market", + "signature": true, + "launch_mode": "browser" + } + ], + "version": 5, + "accounts": { + "42220:0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x635032605337aB36A46D767905108e67EE687a72", + "entrypoint_address": "0xA90904F33df36899d810d040b8d5b3b77265Bb05", + "account_factory_address": "0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x635032605337aB36A46D767905108e67EE687a72", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://selcoupdepouce.be", + "logo": "https://topup.citizenwallet.xyz/communities/selcoupdepouce/sel-coin.svg", + "name": "Bonne Heure", + "alias": "selcoupdepouce", + "hidden": true, + "profile": { + "address": "0xfB8F1e7ED42599638B3c509679E2F43937002C56", + "chain_id": 42220 + }, + "description": "Système d'Échange Local de Villers-la-Ville", + "primary_token": { + "address": "0x5Cdbc862BF4E20D98456D4c41D4A5239aDd496d3", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/selcoupdepouce" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x12e26FAED228c425BceA8a8dd7658a9CeD944dd9": { + "name": "CI token", + "symbol": "CIT", + "address": "0x12e26FAED228c425BceA8a8dd7658a9CeD944dd9", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x452F7ff3e55fe29f481841985dE7f4939FD645fa", + "entrypoint_address": "0xB8d9412f3A91A00ca762B5c35cd0863E9b716D68", + "account_factory_address": "0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970" + }, + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x452F7ff3e55fe29f481841985dE7f4939FD645fa", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "community": { + "url": "https://citizenwallet.xyz/cit", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/cit.celo.svg", + "name": "CI token", + "alias": "cit.celo", + "hidden": true, + "profile": { + "address": "0x4cB296BEc9FAd0B5e1E4FF1A2F307B425724AC82", + "chain_id": 42220 + }, + "description": "Monnaie locale du Cercle Informatique de l’ULB", + "primary_token": { + "address": "0x12e26FAED228c425BceA8a8dd7658a9CeD944dd9", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/cit.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "cards": { + "42220:0xA3E1446E332a098A1f3b0555c5d149b4784A095F": { + "type": "classic", + "address": "0xA3E1446E332a098A1f3b0555c5d149b4784A095F", + "chain_id": 42220 + } + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451": { + "name": "Wolu", + "symbol": "WOLU", + "address": "0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0xF2EFEC3cBFaDE0bB6108620cbF7Cc608d27DCF3c", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0x8474153A00C959f2cB64852949954DBC68415Bb3": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0xF2EFEC3cBFaDE0bB6108620cbF7Cc608d27DCF3c", + "entrypoint_address": "0x0F805BC1ED718FB9C7C18439cB11E1C17C6538C4", + "account_factory_address": "0x8474153A00C959f2cB64852949954DBC68415Bb3" + } + }, + "community": { + "url": "https://wolugo.be", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/wolugo.svg", + "name": "Wolugo", + "alias": "wallet.wolugo.be", + "theme": { + "primary": "#81e2c1" + }, + "hidden": true, + "profile": { + "address": "0x07e7b95B35866302b3A089feF4CFA3061061a51d", + "chain_id": 42220 + }, + "description": "A community for the Woluwe-Saint-Pierre civic engagement platform", + "card_factory": { + "address": "0xA3E1446E332a098A1f3b0555c5d149b4784A095F", + "chain_id": 42220 + }, + "custom_domain": "wallet.wolugo.be", + "primary_token": { + "address": "0x13Dd4B3cD2f2Be3eb41cD0C3E2ce9F8d8C93A451", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.wolugo.be" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0xc53Cb35591959cA62471dA9fF6AC16629A89874a": { + "name": "Woluwe Test Coin", + "symbol": "WTC", + "address": "0xc53Cb35591959cA62471dA9fF6AC16629A89874a", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x3fefC19674f3F6E43B1dFf1861E07c303B9eAAc9", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xE79E19594A749330036280c685E2719d58d99052": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x3fefC19674f3F6E43B1dFf1861E07c303B9eAAc9", + "entrypoint_address": "0x1EaF6B6A6967608aF6c77224f087b042095891EB", + "account_factory_address": "0xE79E19594A749330036280c685E2719d58d99052" + } + }, + "community": { + "url": "https://wollet-v2.citizenwallet.net/token", + "logo": "https://wtc.celo.citizenwallet.xyz/wallet-config/_images/wtc.celo.svg", + "name": "Woluwe Test", + "alias": "wtc.celo", + "hidden": true, + "profile": { + "address": "0xB99a7B1574f051020EB4cb2fce5d48EE07592AfF", + "chain_id": 42220 + }, + "description": "Local currency for the Woluwe Test community.", + "primary_token": { + "address": "0xc53Cb35591959cA62471dA9fF6AC16629A89874a", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wtc.celo" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://sepolia.basescan.org", + "name": "Base Sepolia Explorer" + }, + "chains": { + "84532": { + "id": 84532, + "node": { + "url": "https://84532.engine.citizenwallet.xyz", + "ws_url": "wss://84532.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "84532:0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e": { + "name": "ETHGlobal London Token", + "symbol": "ETHLDN", + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 84532, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "84532:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 84532, + "paymaster_type": "cw-safe", + "paymaster_address": "0x389182aCCeE26D953d5188BF4b92c49339DcC9FC", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "84532:0xc1654087C580f868F08E34cd1c01eDB1d3673b82": { + "chain_id": 84532, + "paymaster_type": "cw", + "paymaster_address": "0x389182aCCeE26D953d5188BF4b92c49339DcC9FC", + "entrypoint_address": "0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE", + "account_factory_address": "0xc1654087C580f868F08E34cd1c01eDB1d3673b82" + } + }, + "community": { + "url": "https://en.wikipedia.org/wiki/USD_Coin", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/testnet-ethldn.svg", + "name": "ETHGlobal London Token", + "alias": "testnet-ethldn", + "hidden": true, + "profile": { + "address": "0x0785D720279f42326846D5396b5F44b97d0BfECd", + "chain_id": 84532 + }, + "description": "The community of people using ETHLDN on Base.", + "primary_token": { + "address": "0x9b1a0D2951b11Ac26A6cBbd5aEf2c4cb014b3B6e", + "chain_id": 84532 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 84532 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/testnet-ethldn" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "CELO Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x3C960E72BBbD837293e75080E1d0Fee6a4640357": { + "name": "Celo Community Point", + "symbol": "CeloC", + "address": "0x3C960E72BBbD837293e75080E1d0Fee6a4640357", + "chain_id": 42220, + "decimals": 6, + "standard": "erc20" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x7f4011845Ea914b6cefc60629e1e00600c972c75", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + }, + "42220:0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA": { + "chain_id": 42220, + "paymaster_type": "cw", + "paymaster_address": "0x7f4011845Ea914b6cefc60629e1e00600c972c75", + "entrypoint_address": "0x66fE9c22CcA49B257dd4F00508AC90198d99Bf27", + "account_factory_address": "0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA" + } + }, + "community": { + "url": "https://citizenwallet.xyz", + "logo": "https://celo-c.citizenwallet.xyz/uploads/logo.svg", + "name": "Celo Community Point", + "alias": "celo-c.citizenwallet.xyz", + "hidden": true, + "profile": { + "address": "0x14004E13907282cFaD05f742022E56926eE92dAd", + "chain_id": 42220 + }, + "description": "This is a community for the Celo Point", + "primary_token": { + "address": "0x3C960E72BBbD837293e75080E1d0Fee6a4640357", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/celo-c.citizenwallet.xyz" + }, + { + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x56744910f7dEcD48c1a7FA61B4C317b15E99F156": { + "name": "KFMEDIA℠ Pathways for LATAM™", + "symbol": "KFMPFL", + "address": "0x56744910f7dEcD48c1a7FA61B4C317b15E99F156", + "chain_id": 42220, + "decimals": 0, + "standard": "erc1155" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x02BDA8370d9497A5C808B2db237cfaA8f0733F36", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://kingfishersmedia.io", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/kfmpfl.png", + "name": "KFMEDIA℠", + "alias": "wallet.kingfishersmedia.io", + "theme": { + "primary": "#88292c" + }, + "profile": { + "address": "0x5f6FEb03ad8EfeCdD2a837FAA1a29DEA2bAcfd55", + "chain_id": 42220 + }, + "description": "Certified Education Organization. Solving systemic educational disparity using Web3 solutions, removing barriers of entry for underdeveloped economies.", + "custom_domain": "wallet.kingfishersmedia.io", + "primary_token": { + "address": "0x56744910f7dEcD48c1a7FA61B4C317b15E99F156", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.kingfishersmedia.io" + } +] diff --git a/assets/config/v5/debug.json b/assets/config/v5/debug.json new file mode 100644 index 00000000..c1b27ccd --- /dev/null +++ b/assets/config/v5/debug.json @@ -0,0 +1,74 @@ +{ + "ipfs": { + "url": "https://ipfs.internal.citizenwallet.xyz" + }, + "scan": { + "url": "https://celoscan.io", + "name": "Celo Explorer" + }, + "chains": { + "42220": { + "id": 42220, + "node": { + "url": "https://42220.engine.citizenwallet.xyz", + "ws_url": "wss://42220.engine.citizenwallet.xyz" + } + } + }, + "tokens": { + "42220:0x56744910f7dEcD48c1a7FA61B4C317b15E99F156": { + "name": "KFMEDIA℠ Pathways for LATAM™", + "symbol": "KFMPFL", + "address": "0x56744910f7dEcD48c1a7FA61B4C317b15E99F156", + "chain_id": 42220, + "decimals": 0, + "standard": "erc1155" + } + }, + "version": 5, + "accounts": { + "42220:0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185": { + "chain_id": 42220, + "paymaster_type": "cw-safe", + "paymaster_address": "0x02BDA8370d9497A5C808B2db237cfaA8f0733F36", + "entrypoint_address": "0x7079253c0358eF9Fd87E16488299Ef6e06F403B6", + "account_factory_address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185" + } + }, + "sessions": { + "42220:0xE2F3DC3E638113b9496060349e5332963d9C1152": { + "chain_id": 42220, + "module_address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "factory_address": "0xEd0cD3886b84369A0e29Db9a4480ADF5051c76C9", + "provider_address": "0xF3004A1690f97Cf5d307eDc5958a7F76b62f9FC9" + } + }, + "community": { + "url": "https://kingfishersmedia.io", + "logo": "https://assets.citizenwallet.xyz/wallet-config/_images/kfmpfl.png", + "name": "KFMEDIA℠", + "alias": "wallet.kingfishersmedia.io", + "theme": { + "primary": "#88292c" + }, + "profile": { + "address": "0x5f6FEb03ad8EfeCdD2a837FAA1a29DEA2bAcfd55", + "chain_id": 42220 + }, + "description": "Certified Education Organization. Solving systemic educational disparity using Web3 solutions, removing barriers of entry for underdeveloped economies.", + "custom_domain": "wallet.kingfishersmedia.io", + "primary_token": { + "address": "0x56744910f7dEcD48c1a7FA61B4C317b15E99F156", + "chain_id": 42220 + }, + "primary_account_factory": { + "address": "0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185", + "chain_id": 42220 + }, + "primary_session_manager": { + "address": "0xE2F3DC3E638113b9496060349e5332963d9C1152", + "chain_id": 42220 + } + }, + "config_location": "https://my.citizenwallet.xyz/api/communities/wallet.kingfishersmedia.io" +} diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b35942fc..bbdd1317 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,7 +13,7 @@ PODS: - Flutter - connectivity_plus (0.0.1): - Flutter - - credential_manager (1.0.4): + - credential_manager_ios (2.0.5): - Flutter - DKImagePickerController/Core (4.3.9): - DKImagePickerController/ImageDataManager @@ -49,37 +49,37 @@ PODS: - file_picker (0.0.1): - DKImagePickerController/PhotoGallery - Flutter - - Firebase/CoreOnly (11.10.0): - - FirebaseCore (~> 11.10.0) - - Firebase/Messaging (11.10.0): + - Firebase/CoreOnly (11.15.0): + - FirebaseCore (~> 11.15.0) + - Firebase/Messaging (11.15.0): - Firebase/CoreOnly - - FirebaseMessaging (~> 11.10.0) - - firebase_core (3.13.1): - - Firebase/CoreOnly (= 11.10.0) + - FirebaseMessaging (~> 11.15.0) + - firebase_core (3.15.2): + - Firebase/CoreOnly (= 11.15.0) - Flutter - - firebase_messaging (15.2.6): - - Firebase/Messaging (= 11.10.0) + - firebase_messaging (15.2.10): + - Firebase/Messaging (= 11.15.0) - firebase_core - Flutter - - FirebaseCore (11.10.0): - - FirebaseCoreInternal (~> 11.10.0) - - GoogleUtilities/Environment (~> 8.0) - - GoogleUtilities/Logger (~> 8.0) - - FirebaseCoreInternal (11.10.0): - - "GoogleUtilities/NSData+zlib (~> 8.0)" - - FirebaseInstallations (11.10.0): - - FirebaseCore (~> 11.10.0) - - GoogleUtilities/Environment (~> 8.0) - - GoogleUtilities/UserDefaults (~> 8.0) + - FirebaseCore (11.15.0): + - FirebaseCoreInternal (~> 11.15.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (11.15.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (11.15.0): + - FirebaseCore (~> 11.15.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) - PromisesObjC (~> 2.4) - - FirebaseMessaging (11.10.0): - - FirebaseCore (~> 11.10.0) + - FirebaseMessaging (11.15.0): + - FirebaseCore (~> 11.15.0) - FirebaseInstallations (~> 11.0) - GoogleDataTransport (~> 10.0) - - GoogleUtilities/AppDelegateSwizzler (~> 8.0) - - GoogleUtilities/Environment (~> 8.0) - - GoogleUtilities/Reachability (~> 8.0) - - GoogleUtilities/UserDefaults (~> 8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Reachability (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) - nanopb (~> 3.30910.0) - Flutter (1.0.0) - flutter_inappwebview_ios (0.0.1): @@ -178,7 +178,7 @@ PODS: DEPENDENCIES: - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - - credential_manager (from `.symlinks/plugins/credential_manager/ios`) + - credential_manager_ios (from `.symlinks/plugins/credential_manager_ios/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) @@ -225,8 +225,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/audioplayers_darwin/ios" connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" - credential_manager: - :path: ".symlinks/plugins/credential_manager/ios" + credential_manager_ios: + :path: ".symlinks/plugins/credential_manager_ios/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" firebase_core: @@ -267,18 +267,18 @@ SPEC CHECKSUMS: AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d - credential_manager: feb21034894e469e3686461dc96fb24bb7d350e4 + credential_manager_ios: fd1d96ef11fa3d76f868f038342de171c3bc2b28 DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 file_picker: be9a674155d9f334323856cb266e0d145d75d5c0 - Firebase: 1fe1c0a7d9aaea32efe01fbea5f0ebd8d70e53a2 - firebase_core: 3c2f323cae65c97a636a05a23b17730ef93df2cf - firebase_messaging: 456e01ff29a451c90097d0b45925551d5be0c143 - FirebaseCore: 8344daef5e2661eb004b177488d6f9f0f24251b7 - FirebaseCoreInternal: ef4505d2afb1d0ebbc33162cb3795382904b5679 - FirebaseInstallations: 9980995bdd06ec8081dfb6ab364162bdd64245c3 - FirebaseMessaging: 2b9f56aa4ed286e1f0ce2ee1d413aabb8f9f5cb9 - Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e + firebase_core: 99a37263b3c27536063a7b601d9e2a49400a433c + firebase_messaging: bf6697c61f31c7cc0f654131212ff04c0115c2c7 + FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e + FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4 + FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843 + FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 google_sign_in_ios: 7411fab6948df90490dc4620ecbcabdc3ca04017 diff --git a/lib/main.dart b/lib/main.dart index f40375a6..41741671 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -76,7 +76,7 @@ FutureOr appRunner() async { } final AppDBService appDBService = AppDBService(); - await appDBService.init('appv4'); + await appDBService.init('appv5'); final numConfigs = (await appDBService.communities.getAll()).length; config.singleCommunityMode = numConfigs < 2; diff --git a/lib/services/accounts/accounts.dart b/lib/services/accounts/accounts.dart index 3edeaf64..a939c4d8 100644 --- a/lib/services/accounts/accounts.dart +++ b/lib/services/accounts/accounts.dart @@ -14,7 +14,7 @@ abstract class AccountsOptionsInterface {} /// /// This is used to store wallet backups and the implementation is platform specific. abstract class AccountsServiceInterface { - final int _version = 4; + final int _version = 7; int get version => _version; diff --git a/lib/services/accounts/backup.dart b/lib/services/accounts/backup.dart index f658f697..32c5fee5 100644 --- a/lib/services/accounts/backup.dart +++ b/lib/services/accounts/backup.dart @@ -81,3 +81,31 @@ class BackupWallet { String get key => '$address@$alias'; String get value => privateKey; } + +class BackupWalletV5 extends BackupWallet { + final String accountFactoryAddress; + + BackupWalletV5({ + required super.address, + required super.alias, + required super.privateKey, + required String accountFactoryAddress, + }) : accountFactoryAddress = + EthereumAddress.fromHex(accountFactoryAddress).hexEip55; + + // Fixes the 'json' super parameter lint + BackupWalletV5.fromJson(super.json) + : accountFactoryAddress = + EthereumAddress.fromHex(json['accountFactoryAddress']).hexEip55, + super.fromJson(); + + @override + Map toJson() { + final json = super.toJson(); + json['accountFactoryAddress'] = accountFactoryAddress; + return json; + } + + @override + String get key => '$address@$accountFactoryAddress@$alias'; +} diff --git a/lib/services/accounts/native/android.dart b/lib/services/accounts/native/android.dart index 83a074a1..ef22ded1 100644 --- a/lib/services/accounts/native/android.dart +++ b/lib/services/accounts/native/android.dart @@ -1,3 +1,4 @@ +import 'package:citizenwallet/services/config/utils.dart'; import 'package:citizenwallet/services/credentials/credentials.dart'; import 'package:citizenwallet/services/db/backup/db.dart'; import 'package:citizenwallet/utils/encrypt.dart'; @@ -6,6 +7,7 @@ import 'package:citizenwallet/services/db/backup/accounts.dart'; import 'package:citizenwallet/services/accounts/backup.dart'; import 'package:citizenwallet/services/accounts/accounts.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:web3dart/crypto.dart'; @@ -66,6 +68,8 @@ class AndroidAccountsService extends AccountsServiceInterface { alias: legacyBackup.alias, address: EthereumAddress.fromHex(legacyBackup.address), name: legacyBackup.name, + accountFactoryAddress: EthereumAddress.fromHex( + getAccountFactoryAddressByAlias(legacyBackup.alias)), ); await _accountsDB.accounts.insert(account); @@ -90,6 +94,161 @@ class AndroidAccountsService extends AccountsServiceInterface { } } }, + 5: () async { + // bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/android.dart#L146 + }, + 6: () async { + // bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/android.dart#L251 + }, + 7: () async { + // This migration handles two paths: + // - AppKevin (v6 -> v7): Clean dirty keys with wrong accountFactoryAddress + // - AppOthers (v4 -> v7): Migrate from old format to new format + + // Read all credentials from secure storage + final allValues = await _credentials.readAll(); + + // Separate keys into different formats + final oldFormatKeys = []; // address@alias + final dirtyNewFormatKeys = + []; // address@accountFactoryAddress@alias (dirty) + + for (final key in allValues.keys) { + if (key.startsWith(backupPrefix) || + key == versionPrefix || + key == pinCodeKey || + key == pinCodeCheckKey) { + continue; + } + + final parts = key.split('@'); + + // Check for old format: address@alias (2 parts) + if (parts.length == 2) { + try { + EthereumAddress.fromHex(parts[0]); + oldFormatKeys.add(key); + } catch (_) { + // Not a valid address, skip + } + } + // Check for new format: address@accountFactoryAddress@alias (3 parts) + else if (parts.length == 3) { + try { + EthereumAddress.fromHex(parts[0]); + EthereumAddress.fromHex(parts[1]); + dirtyNewFormatKeys.add(key); + } catch (_) { + // Not valid addresses, skip + } + } + } + + final toDelete = []; + + // Handle AppOthers path: Migrate old format keys to new format + for (final oldKey in oldFormatKeys) { + final privateKeyValue = allValues[oldKey]; + if (privateKeyValue == null) { + continue; + } + + final parts = oldKey.split('@'); + if (parts.length != 2) { + continue; + } + + final address = parts[0]; + final alias = parts[1]; + + try { + // Get the correct account factory address for this alias + final accountFactoryAddress = + getAccountFactoryAddressByAlias(alias); + + // Create a BackupWalletV5 with the new format + final backup = BackupWalletV5( + address: address, + alias: alias, + accountFactoryAddress: accountFactoryAddress, + privateKey: privateKeyValue, + ); + + // Write the credential with the new key format + await _credentials.write(backup.key, backup.value); + + debugPrint('Migrated old format key: $oldKey -> ${backup.key}'); + + // Mark old key for deletion + toDelete.add(oldKey); + } catch (e) { + debugPrint('Error migrating key $oldKey: $e'); + continue; + } + } + + // Handle AppKevin path: Clean dirty new format keys + for (final dirtyKey in dirtyNewFormatKeys) { + final privateKeyValue = allValues[dirtyKey]; + if (privateKeyValue == null) { + continue; + } + + final parts = dirtyKey.split('@'); + if (parts.length != 3) { + continue; + } + + final address = parts[0]; + final dirtyAccountFactoryAddress = parts[1]; + final alias = parts[2]; + + try { + // Get the CORRECT account factory address for this alias + final correctAccountFactoryAddress = + getAccountFactoryAddressByAlias(alias); + + // Check if the dirty key has the wrong accountFactoryAddress + if (dirtyAccountFactoryAddress.toLowerCase() != + correctAccountFactoryAddress.toLowerCase()) { + debugPrint( + 'Found dirty key with wrong accountFactoryAddress: $dirtyKey'); + debugPrint(' Dirty: $dirtyAccountFactoryAddress'); + debugPrint(' Correct: $correctAccountFactoryAddress'); + + // Create a BackupWalletV5 with the CORRECT account factory address + final cleanBackup = BackupWalletV5( + address: address, + alias: alias, + accountFactoryAddress: correctAccountFactoryAddress, + privateKey: privateKeyValue, + ); + + // Write the credential with the correct key format + await _credentials.write(cleanBackup.key, cleanBackup.value); + + debugPrint('Cleaned dirty key: $dirtyKey -> ${cleanBackup.key}'); + + // Mark dirty key for deletion + toDelete.add(dirtyKey); + } else { + // Key already has correct accountFactoryAddress, no action needed + debugPrint('Key already correct: $dirtyKey'); + } + } catch (e,s) { + debugPrint('Error cleaning dirty key $dirtyKey: $e'); + debugPrintStack(stackTrace: s); + continue; + } + } + + // Delete all old and dirty keys + // TODO: delete old keys after testing + // for (final key in toDelete) { + // await _credentials.delete(key); + // debugPrint('Deleted old/dirty key: $key'); + // } + }, }; // run all migrations @@ -115,7 +274,14 @@ class AndroidAccountsService extends AccountsServiceInterface { final List accounts = await _accountsDB.accounts.all(); for (final account in accounts) { - final privateKey = await _credentials.read(account.id); + final backupKey = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: '', + ).key; + + final privateKey = await _credentials.read(backupKey); if (privateKey == null) { continue; } @@ -135,9 +301,16 @@ class AndroidAccountsService extends AccountsServiceInterface { return; } + final backup = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: bytesToHex(account.privateKey!.privateKey), + ); + await _credentials.write( - account.id, - bytesToHex(account.privateKey!.privateKey), + backup.key, + backup.value, ); } @@ -153,7 +326,14 @@ class AndroidAccountsService extends AccountsServiceInterface { return null; } - final privateKey = await _credentials.read(account.id); + final backupKey = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: '', + ).key; + + final privateKey = await _credentials.read(backupKey); if (privateKey == null) { return account; } @@ -172,16 +352,28 @@ class AndroidAccountsService extends AccountsServiceInterface { // delete wallet backup @override Future deleteAccount(String address, String alias) async { + // Get the account before deleting it + final account = + await _accountsDB.accounts.get(EthereumAddress.fromHex(address), alias); + + if (account == null) { + return; + } + await _accountsDB.accounts.delete( EthereumAddress.fromHex(address), alias, ); + final backupKey = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: '', + ).key; + await _credentials.delete( - getAccountID( - EthereumAddress.fromHex(address), - alias, - ), + backupKey, ); } @@ -279,9 +471,16 @@ class AndroidAccountsService extends AccountsServiceInterface { final allAccounts = await getAllAccounts(); // accounts with private keys for (final account in allAccounts) { + final backup = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: bytesToHex(account.privateKey!.privateKey), + ); + await _credentials.write( - account.id, - bytesToHex(account.privateKey!.privateKey), + backup.key, + backup.value, ); // null private key before updating in DB diff --git a/lib/services/accounts/native/apple.dart b/lib/services/accounts/native/apple.dart index 849f9f1f..371e5c91 100644 --- a/lib/services/accounts/native/apple.dart +++ b/lib/services/accounts/native/apple.dart @@ -2,10 +2,12 @@ import 'package:citizenwallet/services/accounts/backup.dart'; import 'package:citizenwallet/services/accounts/accounts.dart'; import 'package:citizenwallet/services/accounts/options.dart'; import 'package:citizenwallet/services/accounts/utils.dart'; +import 'package:citizenwallet/services/config/utils.dart'; import 'package:citizenwallet/services/credentials/credentials.dart'; import 'package:citizenwallet/services/credentials/native/apple.dart'; import 'package:citizenwallet/services/db/backup/accounts.dart'; import 'package:citizenwallet/services/db/backup/db.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:web3dart/credentials.dart'; import 'package:web3dart/crypto.dart'; @@ -170,6 +172,8 @@ class AppleAccountsService extends AccountsServiceInterface { alias: legacyBackup.alias, address: EthereumAddress.fromHex(legacyBackup.address), name: legacyBackup.name, + accountFactoryAddress: EthereumAddress.fromHex( + getAccountFactoryAddressByAlias(legacyBackup.alias)), ); await _accountsDB.accounts.insert(account); @@ -203,6 +207,160 @@ class AppleAccountsService extends AccountsServiceInterface { } } }, + 5: () async { + // bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/apple.dart#L154 + }, + 6: () async { + // bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/apple.dart#L264 + }, + 7: () async { + // This migration handles two paths: + // - AppKevin (v6 -> v7): Clean dirty keys with wrong accountFactoryAddress + // - AppOthers (v4 -> v7): Migrate from old format to new format + + // Read all credentials from Keychain + final allValues = await _credentials.readAll(); + + // Separate keys into different formats + final oldFormatKeys = []; // address@alias + final dirtyNewFormatKeys = + []; // address@accountFactoryAddress@alias (dirty) + + for (final key in allValues.keys) { + if (key.startsWith(backupPrefix) || key == versionPrefix) { + continue; + } + + final parts = key.split('@'); + + // Check for old format: address@alias (2 parts) + if (parts.length == 2) { + try { + EthereumAddress.fromHex(parts[0]); + oldFormatKeys.add(key); + } catch (_) { + // Not a valid address, skip + } + } + // Check for new format: address@accountFactoryAddress@alias (3 parts) + else if (parts.length == 3) { + try { + EthereumAddress.fromHex(parts[0]); + EthereumAddress.fromHex(parts[1]); + dirtyNewFormatKeys.add(key); + } catch (_) { + // Not valid addresses, skip + } + } + } + + final toDelete = []; + + // Handle AppOthers path: Migrate old format keys to new format + for (final oldKey in oldFormatKeys) { + final privateKeyValue = allValues[oldKey]; + if (privateKeyValue == null) { + continue; + } + + final parts = oldKey.split('@'); + if (parts.length != 2) { + continue; + } + + final address = parts[0]; + final alias = parts[1]; + + try { + // Get the correct account factory address for this alias + final accountFactoryAddress = + getAccountFactoryAddressByAlias(alias); + + // Create a BackupWalletV5 with the new format + final backup = BackupWalletV5( + address: address, + alias: alias, + accountFactoryAddress: accountFactoryAddress, + privateKey: privateKeyValue, + ); + + // Write the credential with the new key format + await _credentials.write(backup.key, backup.value); + + debugPrint('Migrated old format key: $oldKey -> ${backup.key}'); + + // Mark old key for deletion + toDelete.add(oldKey); + } catch (e) { + debugPrint('Error migrating key $oldKey: $e'); + continue; + } + } + + // Handle AppKevin path: Clean dirty new format keys + for (final dirtyKey in dirtyNewFormatKeys) { + final privateKeyValue = allValues[dirtyKey]; + if (privateKeyValue == null) { + continue; + } + + final parts = dirtyKey.split('@'); + if (parts.length != 3) { + continue; + } + + final address = parts[0]; + final dirtyAccountFactoryAddress = parts[1]; + final alias = parts[2]; + + try { + // Get the CORRECT account factory address for this alias + final correctAccountFactoryAddress = + getAccountFactoryAddressByAlias(alias); + + // Check if the dirty key has the wrong accountFactoryAddress + if (dirtyAccountFactoryAddress.toLowerCase() != + correctAccountFactoryAddress.toLowerCase()) { + debugPrint( + 'Found dirty key with wrong accountFactoryAddress: $dirtyKey'); + debugPrint(' Dirty: $dirtyAccountFactoryAddress'); + debugPrint(' Correct: $correctAccountFactoryAddress'); + + // Create a BackupWalletV5 with the CORRECT account factory address + final cleanBackup = BackupWalletV5( + address: address, + alias: alias, + accountFactoryAddress: correctAccountFactoryAddress, + privateKey: privateKeyValue, + ); + + // Write the credential with the correct key format + await _credentials.write(cleanBackup.key, cleanBackup.value); + + debugPrint('Cleaned dirty key: $dirtyKey -> ${cleanBackup.key}'); + + // Mark dirty key for deletion + toDelete.add(dirtyKey); + } else { + // Key already has correct accountFactoryAddress, no action needed + debugPrint('Key already correct: $dirtyKey'); + } + } catch (e,s) { + debugPrint('Error cleaning dirty key $dirtyKey: $e'); + debugPrintStack(stackTrace: s); + continue; + } + } + + // Delete all old format keys + // TODO: delete old keys after testing + // for (final key in toDelete) { + // final saved = await _credentials.containsKey(key); + // if (saved) { + // await _credentials.delete(key); + // } + // } + }, }; // run all migrations @@ -228,7 +386,14 @@ class AppleAccountsService extends AccountsServiceInterface { final List accounts = await _accountsDB.accounts.all(); for (final account in accounts) { - final privateKey = await _credentials.read(account.id); + final backupKey = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: '', + ).key; + + final privateKey = await _credentials.read(backupKey); if (privateKey == null) { continue; } @@ -248,9 +413,16 @@ class AppleAccountsService extends AccountsServiceInterface { return; } + final backup = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: bytesToHex(account.privateKey!.privateKey), + ); + await _credentials.write( - account.id, - bytesToHex(account.privateKey!.privateKey), + backup.key, + backup.value, ); } @@ -266,7 +438,14 @@ class AppleAccountsService extends AccountsServiceInterface { return null; } - final privateKey = await _credentials.read(account.id); + final backupKey = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: '', + ).key; + + final privateKey = await _credentials.read(backupKey); if (privateKey == null) { return account; } @@ -285,16 +464,29 @@ class AppleAccountsService extends AccountsServiceInterface { // delete wallet backup @override Future deleteAccount(String address, String alias) async { + final account = await _accountsDB.accounts.get( + EthereumAddress.fromHex(address), + alias, + ); + + if (account == null) { + return; + } + await _accountsDB.accounts.delete( EthereumAddress.fromHex(address), alias, ); + final backupKey = BackupWalletV5( + address: account.address.hexEip55, + alias: account.alias, + accountFactoryAddress: account.accountFactoryAddress.hexEip55, + privateKey: '', + ).key; + await _credentials.delete( - getAccountID( - EthereumAddress.fromHex(address), - alias, - ), + backupKey, ); } diff --git a/lib/services/accounts/utils.dart b/lib/services/accounts/utils.dart index 023ca3bb..c48ad373 100644 --- a/lib/services/accounts/utils.dart +++ b/lib/services/accounts/utils.dart @@ -15,7 +15,6 @@ import 'package:web3dart/web3dart.dart'; Future getLegacyAccountAddress( LegacyBackupWallet backup) async { try { - // final config = await ConfigService().getConfig(backup.alias); final community = await AppDBService().communities.get(backup.alias); if (community == null) { diff --git a/lib/services/config/config.dart b/lib/services/config/config.dart index 01b02434..46eed9a1 100644 --- a/lib/services/config/config.dart +++ b/lib/services/config/config.dart @@ -726,6 +726,25 @@ class Config { return primaryAccountAbstraction; } + ERC4337Config getAccountAbstractionConfig({ + required String accountFactoryAddress, + }) { + // Build the full address key using chainId:accountFactoryAddress format + final chainId = community.primaryToken.chainId; + final fullAddress = '$chainId:$accountFactoryAddress'; + + // Try to find the account config + final accountConfig = accounts[fullAddress]; + + if (accountConfig == null) { + throw Exception( + 'Account Abstraction Config not found for address: $fullAddress', + ); + } + + return accountConfig; + } + CardsConfig? getPrimaryCardManager() { return cards?[community.primaryCardManager?.fullAddress]; } @@ -740,13 +759,21 @@ class Config { return chain.node.url; } - String getRpcUrl(String chainId) { + String getRpcUrl({ + required String chainId, + required String accountFactoryAddress, + }) { final chain = chains[chainId]; if (chain == null) { throw Exception('Chain not found'); } - return '${chain.node.url}/v1/rpc/${getPrimaryAccountAbstractionConfig().paymasterAddress}'; + // Get the account config (primary or specific based on accountFactoryAddress) + final accountConfig = getAccountAbstractionConfig( + accountFactoryAddress: accountFactoryAddress, + ); + + return '${chain.node.url}/v1/rpc/${accountConfig.paymasterAddress}'; } } diff --git a/lib/services/config/service.dart b/lib/services/config/service.dart index 89b998ec..aa9fda6c 100644 --- a/lib/services/config/service.dart +++ b/lib/services/config/service.dart @@ -30,7 +30,7 @@ class ConfigService { static const String communityConfigListS3FileName = 'communities'; static const String communityDebugFileName = 'debug'; - static const int version = 4; + static const int version = 5; final PreferencesService _pref = PreferencesService(); late APIService _api; @@ -105,6 +105,14 @@ class ConfigService { } } + // NEW: Try direct fetch first (more efficient) + try { + final config = await getConfigByAlias(alias); + if (config != null) { + return config; + } + } catch (_) {} + try { // fetch the config and await _configs = await getConfigs(location: location); @@ -145,25 +153,33 @@ class ConfigService { return [Config.fromJson(response)]; } - final response = await _api.get( - url: - '/v$version/$communityConfigListFileName.json?cachebuster=${generateCacheBusterValue()}'); + final response = await _api.get(url: '/api/communities'); _pref.setConfigs(response); - final configs = (response as List).map((e) => Config.fromJson(e)).toList(); + // The API returns an array of wrapper objects with the config nested in the 'json' field + final configs = (response as List).map((e) { + final configData = e['json'] as Map; + return Config.fromJson(configData); + }).toList(); return configs; } Future> getLocalConfigs() async { - final localConfigs = jsonDecode(await rootBundle.loadString( - 'assets/config/v$version/$communityConfigListFileName.json')); + try { + final localConfigs = jsonDecode(await rootBundle.loadString( + 'assets/config/v$version/$communityConfigListFileName.json')); - final configs = - (localConfigs as List).map((e) => Config.fromJson(e)).toList(); + final configs = + (localConfigs as List).map((e) => Config.fromJson(e)).toList(); - return configs; + return configs; + } catch (e, s) { + debugPrint('ERROR in getLocalConfigs: $e'); + debugPrintStack(stackTrace: s); + return []; + } } Future getRemoteConfig(String remoteConfigUrl) async { @@ -184,7 +200,19 @@ class ConfigService { final dynamic response = await remote.get(url: '?cachebuster=${generateCacheBusterValue()}'); - final config = Config.fromJson(response); + if (response == null) { + debugPrint('Empty response for remote config'); + return null; + } + + // The API returns a wrapper object with the config nested in the 'json' field + final configData = response['json'] as Map?; + if (configData == null) { + debugPrint('No json field in response for remote config'); + return null; + } + + final config = Config.fromJson(configData); return config; } catch (e, s) { @@ -206,16 +234,47 @@ class ConfigService { return configs; } - final List response = await _api.get( - url: - '/v$version/$communityConfigListS3FileName.json?cachebuster=${generateCacheBusterValue()}'); + final List response = await _api.get(url: '/api/communities'); - final List communities = - response.map((item) => Config.fromJson(item)).toList(); + // The API returns an array of wrapper objects with the config nested in the 'json' field + final List communities = response.map((item) { + final configData = item['json'] as Map; + return Config.fromJson(configData); + }).toList(); return communities; } + Future getConfigByAlias(String alias) async { + if (kDebugMode) { + final localConfigs = jsonDecode(await rootBundle.loadString( + 'assets/config/v$version/$communityConfigListFileName.json')); + + final configs = + (localConfigs as List).map((e) => Config.fromJson(e)).toList(); + return configs.firstWhereOrNull((c) => c.community.alias == alias); + } + + try { + final response = await _api.get(url: '/api/communities/$alias'); + if (response == null) { + debugPrint('Empty response for config: $alias'); + return null; + } + // The API returns a wrapper object with the config nested in the 'json' field + final configData = response['json'] as Map?; + if (configData == null) { + debugPrint('No json field in response for config: $alias'); + return null; + } + return Config.fromJson(configData); + } catch (e, s) { + debugPrint('Error fetching config for $alias: $e'); + debugPrint('Stacktrace: $s'); + return null; + } + } + Future isCommunityOnline(String indexerUrl) async { final indexer = APIService(baseURL: indexerUrl, netTimeoutSeconds: 20); diff --git a/lib/services/config/utils.dart b/lib/services/config/utils.dart index 7c8a3829..667df7d5 100644 --- a/lib/services/config/utils.dart +++ b/lib/services/config/utils.dart @@ -15,3 +15,87 @@ String fixLegacyAliases(String alias) { return alias == 'localhost' || alias == '' ? defaultAlias : alias; } + +/// migrate the accounts from the accounts migration db (when migrating from old app and you want to put a value in the account secret) +/// hard coded values for these communities (gratitude, bread, wallet.commonshub.brussels, wallet.sfluv.org) +/// if account factory address is '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', return '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' +/// the others just take the primary account factory +const Map configV4PrimaryAccountFactoryMap = { + /****cw-safe (old)*****/ + 'ctzn': '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', + 'txirrin': '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', + 'boliviapay': '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', + 'seldesalm': '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', + 'my.techi.be': '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', + 'wallet.kingfishersmedia.io': '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', + /*********/ + 'gratitude': '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD', + 'bread': '0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9', + 'wallet.commonshub.brussels': '0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87', + 'wallet.sfluv.org': '0x5e987a6c4bb4239d498E78c34e986acf29c81E8e', + /****cw-safe (new)*****/ + 'wallet.berachain.sfluv.org': '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + 'laborhour': '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + 'rooted': '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + /*********/ + 'wallet.pay.brussels': '0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE', + 'wallet.regensunite.earth': '0x9406Cc6185a346906296840746125a0E44976454', + 'gt.celo': '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD', + 'ceur.celo': '0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098', + 'eure.polygon': '0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616', + 'app': '0x270758454C012A1f51428b68aE473D728CCdFe88', + 'usdc.base': '0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99', + 'wallet.oak.community': '0x9406Cc6185a346906296840746125a0E44976454', + 'sbc.polygon': '0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5', + 'zinne': '0x11af2639817692D2b805BcE0e1e405E530B20006', + 'timebank.regensunite.earth': '0x39b77d77f7677997871b304094a05295eb71e240', + 'moos': '0x671f0662de72268d0f3966Fb62dFc6ee6389e244', + 'selcoupdepouce': '0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284', + 'cit.celo': '0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970', + 'wallet.wolugo.be': '0x8474153A00C959f2cB64852949954DBC68415Bb3', + 'wtc.celo': '0xE79E19594A749330036280c685E2719d58d99052', + 'testnet-ethldn': '0xc1654087C580f868F08E34cd1c01eDB1d3673b82', + 'celo-c.citizenwallet.xyz': '0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA', +}; + +const String oldSafeFactory = '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2'; +const String newSafeFactory = '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185'; + +/// Returns the correct account factory address for a given community alias during database migration. +/// +/// Priority logic: +/// 1. Specific hardcoded overrides for: gratitude, bread, wallet.commonshub.brussels, wallet.sfluv.org +/// 2. Safe factory redirection: if the mapped address is '0x940Cbb155161dc0C4aade27a4826a16Ed8ca0cb2', +/// return '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' instead +/// 3. General fallback: return the address from the map +/// 4. Safety: if alias not found, return '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' +String getAccountFactoryAddressByAlias(String alias) { + // List of specific aliases that should keep their original addresses + const Set hardcodedOverrides = { + 'gratitude', + 'bread', + 'wallet.commonshub.brussels', + 'wallet.sfluv.org', + }; + + // 1. Check if this is a hardcoded override + if (hardcodedOverrides.contains(alias)) { + return configV4PrimaryAccountFactoryMap[alias]!; + } + + // Get the address from the map + final String? mappedAddress = configV4PrimaryAccountFactoryMap[alias]; + + // 4. Safety: if alias not found, return new safe factory + if (mappedAddress == null) { + return newSafeFactory; + } + + // 2. Safe factory redirection: if old safe factory, return new safe factory + if (mappedAddress == oldSafeFactory) { + return newSafeFactory; + } + + // 3. General fallback: return the mapped address + return mappedAddress; +} diff --git a/lib/services/db/app/communities.dart b/lib/services/db/app/communities.dart index 46eefac1..ec1f798b 100644 --- a/lib/services/db/app/communities.dart +++ b/lib/services/db/app/communities.dart @@ -3,6 +3,7 @@ import 'package:citizenwallet/services/config/config.dart'; import 'package:citizenwallet/services/config/legacy.dart'; import 'package:citizenwallet/services/config/service.dart'; import 'package:citizenwallet/services/db/db.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:sqflite/sqflite.dart'; @@ -28,6 +29,50 @@ Future> legacyToV4(Database db, String name) async { return v4Configs; } +Future> V5Migration(Database db, String name) async { + try { + final ConfigService config = ConfigService(); + final localConfigs = await config.getLocalConfigs(); + + final List> maps = await db.query(name); + final existingCommunities = List.generate(maps.length, (i) { + return DBCommunity.fromMap(maps[i]); + }); + + final List updatedConfigs = []; + + for (final localConfig in localConfigs) { + final existingCommunity = existingCommunities.firstWhereOrNull( + (c) => c.alias == localConfig.community.alias, + ); + + if (existingCommunity != null) { + // Update existing community, preserve online status + final updatedCommunity = DBCommunity( + alias: localConfig.community.alias, + config: localConfig.toJson(), + hidden: localConfig.community.hidden, + version: localConfig.version, + online: existingCommunity.online, + ); + updatedConfigs.add(updatedCommunity); + } else { + // New community in v5 + updatedConfigs.add(DBCommunity.fromConfig(localConfig)); + } + } + + return updatedConfigs; + } catch (e, s) { + debugPrint('ERROR in V5Migration: $e'); + debugPrintStack(stackTrace: s); + + // Return existing data unchanged on error + final List> maps = await db.query(name); + return List.generate(maps.length, (i) => DBCommunity.fromMap(maps[i])); + } +} + class DBCommunity { final String alias; // index final bool hidden; @@ -118,6 +163,9 @@ class CommunityTable extends DBTable { 2: [ 'V4Migration', ], + 3: [ + 'V5Migration', + ], }; for (var i = oldVersion + 1; i <= newVersion; i++) { @@ -131,6 +179,10 @@ class CommunityTable extends DBTable { final updatedConfigs = await legacyToV4(db, name); await upsert(updatedConfigs); continue; + case 'V5Migration': + final updatedConfigs = await V5Migration(db, name); + await upsert(updatedConfigs); + continue; } await db.execute(query); @@ -144,26 +196,32 @@ class CommunityTable extends DBTable { } Future seed() async { - final localConfigs = await _config.getLocalConfigs(); + try { + // Check if the table is empty + final count = Sqflite.firstIntValue( + await db.rawQuery('SELECT COUNT(*) FROM $name')); - // Check if the table is empty - final count = - Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM $name')); - if (count != null && count > 0) { - return; // Table is not empty, skip seeding - } + if (count != null && count > 0) { + return; // Table is not empty, skip seeding + } - // Prepare batch operation for efficient insertion - final batch = db.batch(); + final localConfigs = await _config.getLocalConfigs(); - for (final config in localConfigs) { - batch.insert( - name, - DBCommunity.fromConfig(config).toMap(), - ); - } + // Prepare batch operation for efficient insertion + final batch = db.batch(); - await batch.commit(noResult: true); + for (final config in localConfigs) { + batch.insert( + name, + DBCommunity.fromConfig(config).toMap(), + ); + } + + await batch.commit(noResult: true); + } catch (e, s) { + debugPrint('Error seeding communities table: $e'); + debugPrintStack(stackTrace: s); + } } Future upsert(List communities) async { diff --git a/lib/services/db/app/db.dart b/lib/services/db/app/db.dart index f73c927d..65e25b60 100644 --- a/lib/services/db/app/db.dart +++ b/lib/services/db/app/db.dart @@ -27,7 +27,7 @@ class AppDBService extends DBService { await communities.migrate(db, oldVersion, newVersion); return; }, - version: 2, + version: 3, ); final db = await databaseFactory.openDatabase( diff --git a/lib/services/db/backup/accounts.dart b/lib/services/db/backup/accounts.dart index 13404623..20248722 100644 --- a/lib/services/db/backup/accounts.dart +++ b/lib/services/db/backup/accounts.dart @@ -1,8 +1,8 @@ import 'dart:convert'; +import 'package:citizenwallet/services/config/utils.dart'; import 'package:citizenwallet/services/db/db.dart'; import 'package:citizenwallet/services/wallet/contracts/profile.dart'; -import 'package:citizenwallet/services/wallet/wallet.dart'; import 'package:flutter/foundation.dart'; import 'package:sqflite/sqlite_api.dart'; import 'package:web3dart/crypto.dart'; @@ -12,6 +12,7 @@ class DBAccount { final String id; final String alias; final EthereumAddress address; + final EthereumAddress accountFactoryAddress; final String name; final UserHandle? userHandle; final String? username; @@ -21,6 +22,7 @@ class DBAccount { DBAccount({ required this.alias, required this.address, + required this.accountFactoryAddress, required this.name, this.username, this.privateKey, @@ -34,6 +36,7 @@ class DBAccount { 'id': id, 'alias': alias, 'address': address.hexEip55, + 'accountFactoryAddress': accountFactoryAddress.hexEip55, if (name.isNotEmpty) 'name': name, 'username': username, 'privateKey': @@ -47,6 +50,8 @@ class DBAccount { return DBAccount( alias: map['alias'], address: EthereumAddress.fromHex(map['address']), + accountFactoryAddress: + EthereumAddress.fromHex(map['accountFactoryAddress']), name: map['name'], username: map['username'], privateKey: map['privateKey'] != null @@ -96,7 +101,8 @@ class AccountsTable extends DBTable { name TEXT NOT NULL, username TEXT, privateKey TEXT, - profile TEXT + profile TEXT, + accountFactoryAddress TEXT NOT NULL ) '''; @@ -113,6 +119,17 @@ class AccountsTable extends DBTable { ], 3: [ 'ALTER TABLE $name ADD COLUMN username TEXT DEFAULT NULL', + ], + 4: [ + // bad migration,https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/db/backup/accounts.dart#L123 + ], + 5: [ + // This migration handles both paths: + // - AppKevin (v4 -> v5): column already exists, just populate + // - AppOthers (v3 -> v5): column doesn't exist, add it then populate + 'AddAccountFactoryAddressIfNotExists', + 'PopulateAccountFactoryAddressMigration', + 'CleanDirtyV4Accounts', ] }; @@ -122,6 +139,20 @@ class AccountsTable extends DBTable { if (queries != null) { for (final query in queries) { try { + switch (query) { + case 'AddAccountFactoryAddressIfNotExists': + await _addAccountFactoryAddressIfNotExists(db, name); + continue; + + case 'PopulateAccountFactoryAddressMigration': + await _populateAccountFactoryAddressMigration(db, name); + continue; + + case 'CleanDirtyV4Accounts': + await _cleanDirtyV4Accounts(db, name); + continue; + } + await db.execute(query); } catch (e, s) { debugPrint('Migration error: $e'); @@ -132,6 +163,145 @@ class AccountsTable extends DBTable { } } + Future _addAccountFactoryAddressIfNotExists( + Database db, + String name, + ) async { + final columnName = 'accountFactoryAddress'; + + // Check if column exists + final tableInfo = await db.rawQuery('PRAGMA table_info($name)'); + final hasColumn = tableInfo.any((col) => col['name'] == columnName); + + if (hasColumn) { + return; + } + + await db + .execute('ALTER TABLE $name ADD COLUMN $columnName TEXT DEFAULT ""'); + } + + Future _populateAccountFactoryAddressMigration( + Database db, String name) async { + // Work directly with raw DB data, not DBAccount objects + List> accounts = await db.query(name); + + for (final Map account in accounts) { + final alias = account['alias'] as String; + final oldId = account['id'] as String; + + final accountFactoryAddress = getAccountFactoryAddressByAlias(alias); + + // Update the accountFactoryAddress column (ID still in old format $address@$alias) + await db.update( + name, + {'accountFactoryAddress': accountFactoryAddress}, + where: 'id = ?', + whereArgs: [oldId], + ); + } + } + + Future _cleanDirtyV4Accounts(Database db, String name) async { + // Get all accounts from the database + List> accounts = await db.query(name); + + for (final Map account in accounts) { + final String currentId = account['id'] as String; + final String alias = account['alias'] as String; + final String addressStr = account['address'] as String; + final String accountFactoryAddressStr = + account['accountFactoryAddress'] as String; + + // Construct what the ID should be in the old format + final String oldFormatId = getAccountID(EthereumAddress.fromHex(addressStr), alias); + + // Construct what the ID would be in the new (bad) format + final String newFormatId = '$addressStr@$accountFactoryAddressStr@$alias'; + + // Check if current ID matches the new (bad) format + if (currentId == newFormatId) { + debugPrint('Cleaning dirty account: $currentId -> $oldFormatId'); + + // Check if an account with the old format ID already exists + final existingOldFormat = await db.query( + name, + where: 'id = ?', + whereArgs: [oldFormatId], + ); + + if (existingOldFormat.isEmpty) { + // No conflict: Insert new row with old ID format + final Map cleanAccount = Map.from(account); + cleanAccount['id'] = oldFormatId; + + await db.insert( + name, + cleanAccount, + conflictAlgorithm: ConflictAlgorithm.replace, + ); + + debugPrint('Inserted clean account with old format ID: $oldFormatId'); + } else { + // Conflict exists: Keep the existing old format, just log + debugPrint( + 'Old format ID already exists, keeping existing: $oldFormatId'); + } + + // Delete the row with new (bad) format ID + await db.delete( + name, + where: 'id = ?', + whereArgs: [currentId], + ); + + debugPrint('Deleted dirty account with new format ID: $currentId'); + } else if (currentId == oldFormatId) { + // Already in correct old format, do nothing + debugPrint('Account already in correct format: $currentId'); + } else { + // Unexpected format - force to old format + debugPrint( + 'Warning: Unexpected ID format, forcing to old format: $currentId -> $oldFormatId'); + + // Check if an account with the old format ID already exists + final existingOldFormat = await db.query( + name, + where: 'id = ?', + whereArgs: [oldFormatId], + ); + + if (existingOldFormat.isEmpty) { + // No conflict: Insert new row with old ID format, preserving all other columns + final Map cleanAccount = Map.from(account); + cleanAccount['id'] = oldFormatId; + + await db.insert( + name, + cleanAccount, + conflictAlgorithm: ConflictAlgorithm.replace, + ); + + debugPrint( + 'Inserted account with corrected old format ID: $oldFormatId'); + } else { + // Conflict exists: Keep the existing old format + debugPrint( + 'Old format ID already exists, keeping existing: $oldFormatId'); + } + + // Delete the row with unexpected format ID + await db.delete( + name, + where: 'id = ?', + whereArgs: [currentId], + ); + + debugPrint('Deleted account with unexpected format ID: $currentId'); + } + } + } + // get account by id Future get(EthereumAddress address, String alias) async { final List> maps = await db.query( diff --git a/lib/services/db/backup/db.dart b/lib/services/db/backup/db.dart index 71ae81af..595fc9b3 100644 --- a/lib/services/db/backup/db.dart +++ b/lib/services/db/backup/db.dart @@ -40,7 +40,7 @@ class AccountBackupDBService extends DBService { return; }, - version: 3, + version: 5, ); final db = await databaseFactory.openDatabase( diff --git a/lib/services/preferences/preferences.dart b/lib/services/preferences/preferences.dart index 14d8a7d6..a6e89ecd 100644 --- a/lib/services/preferences/preferences.dart +++ b/lib/services/preferences/preferences.dart @@ -81,6 +81,15 @@ class PreferencesService { String? get lastAlias => _preferences.getString('lastAlias'); + // save the last account factory address that was opened + Future setLastAccountFactoryAddress(String accountFactoryAddress) async { + await _preferences.setString( + 'lastAccountFactoryAddress', accountFactoryAddress); + } + + String? get lastAccountFactoryAddress => + _preferences.getString('lastAccountFactoryAddress'); + // save the last link that was opened on web Future setLastWalletLink(String link) async { await _preferences.setString('lastWalletLink', link); @@ -160,5 +169,4 @@ class PreferencesService { String? getLanguageCode() { return _preferences.getString('languageCode'); } - } diff --git a/lib/services/wallet/contracts/account_factory.dart b/lib/services/wallet/contracts/account_factory.dart index cf27bffc..113b162d 100644 --- a/lib/services/wallet/contracts/account_factory.dart +++ b/lib/services/wallet/contracts/account_factory.dart @@ -14,7 +14,10 @@ Future accountFactoryServiceFromConfig(Config config, {String? customAccountFactory}) async { final primaryAccountFactory = config.community.primaryAccountFactory; - final url = config.getRpcUrl(primaryAccountFactory.chainId.toString()); + final url = config.getRpcUrl( + chainId: primaryAccountFactory.chainId.toString(), + accountFactoryAddress: primaryAccountFactory.address, + ); // final wsurl = // config.chains[primaryAccountFactory.chainId.toString()]!.node.wsUrl; print('url: $url'); diff --git a/lib/services/wallet/contracts/profile.dart b/lib/services/wallet/contracts/profile.dart index e2296980..d5c1ee71 100644 --- a/lib/services/wallet/contracts/profile.dart +++ b/lib/services/wallet/contracts/profile.dart @@ -167,10 +167,12 @@ class ProfileContract { rcontract = DeployedContract(cabi, EthereumAddress.fromHex(addr)); } +// TODO: await return Future getURL(String addr) async { return contract.get(EthereumAddress.fromHex(addr)); } +// TODO: await return Future getURLFromUsername(String username) async { return contract.getFromUsername( convertStringToUint8List(username, forcePadLength: 32)); diff --git a/lib/services/wallet/wallet.dart b/lib/services/wallet/wallet.dart index afbe4beb..5e592284 100644 --- a/lib/services/wallet/wallet.dart +++ b/lib/services/wallet/wallet.dart @@ -78,6 +78,8 @@ class WalletService { late EthPrivateKey _credentials; // Represents a private key for an Ethereum account. late EthereumAddress _account; // Represents an Ethereum address. + late EthereumAddress _accountFactoryAddress; + late SigAuthService _sigAuth; late StackupEntryPoint @@ -100,6 +102,7 @@ class WalletService { EthPrivateKey get credentials => _credentials; EthereumAddress get address => _credentials.address; EthereumAddress get account => _account; + EthereumAddress get accountFactoryAddress => _accountFactoryAddress; /// retrieves the current balance of the address Future getBalance({String? addr, BigInt? tokenId}) async { @@ -154,6 +157,7 @@ class WalletService { Future init( EthereumAddress account, + EthereumAddress accountFactoryAddress, EthPrivateKey privateKey, NativeCurrency currency, Config config, { @@ -161,16 +165,19 @@ class WalletService { void Function(bool)? onFinished, }) async { _alias = config.community.alias; + _accountFactoryAddress = accountFactoryAddress; final token = config.getPrimaryToken(); - final accountAbstractionConfig = - config.getPrimaryAccountAbstractionConfig(); + + final accountAbstractionConfig = config.getAccountAbstractionConfig( + accountFactoryAddress: accountFactoryAddress.hexEip55); + final chain = config.chains[token.chainId.toString()]; _url = chain!.node.url; _wsurl = chain.node.wsUrl; - final rpcUrl = config.getRpcUrl(token.chainId.toString()); + final rpcUrl = config.getRpcUrl(chainId: token.chainId.toString(), accountFactoryAddress: accountFactoryAddress.hexEip55); _ethClient = Web3Client( rpcUrl, diff --git a/lib/state/app/logic.dart b/lib/state/app/logic.dart index 7ece074d..b8a090ba 100644 --- a/lib/state/app/logic.dart +++ b/lib/state/app/logic.dart @@ -83,8 +83,6 @@ class AppLogic { final address = dbWallet.address.hexEip55; - // final config = await _config.getConfig(dbWallet.alias); - final community = await _appDBService.communities.get(dbWallet.alias); if (community == null) { @@ -132,8 +130,6 @@ class AppLogic { await delay( const Duration(milliseconds: 500)); // smoother launch experience - // final config = await _config.getConfig(alias); - final community = await _appDBService.communities.get(alias); if (community == null) { @@ -193,6 +189,8 @@ class AppLogic { privateKey: credentials, name: token.name, alias: communityConfig.community.alias, + accountFactoryAddress: EthereumAddress.fromHex(communityConfig.community.primaryAccountFactory.address), + )); _theme.changeTheme(communityConfig.community.theme); @@ -285,8 +283,6 @@ class AppLogic { throw Exception('Invalid private key'); } - // final config = await _config.getConfig(alias); - final community = await _appDBService.communities.get(alias); if (community == null) { @@ -308,6 +304,7 @@ class AppLogic { privateKey: credentials, name: name, alias: communityConfig.community.alias, + accountFactoryAddress: EthereumAddress.fromHex(communityConfig.community.primaryAccountFactory.address), ), ); @@ -348,8 +345,6 @@ class AppLogic { final credentials = wallet.privateKey; - // final config = await _config.getConfig(alias); - final community = await _appDBService.communities.get(alias); if (community == null) { @@ -374,6 +369,8 @@ class AppLogic { privateKey: credentials, name: '${token.symbol} Web Account', alias: communityConfig.community.alias, + accountFactoryAddress: EthereumAddress.fromHex(communityConfig.community.primaryAccountFactory.address), + ), ); diff --git a/lib/state/profile/logic.dart b/lib/state/profile/logic.dart index 6c53f64a..6bfc1290 100644 --- a/lib/state/profile/logic.dart +++ b/lib/state/profile/logic.dart @@ -150,6 +150,7 @@ class ProfileLogic { Future loadProfile({String? account, bool online = false}) async { final ethAccount = _wallet.account; final alias = _wallet.alias ?? ''; + final accountFactoryAddress = _wallet.accountFactoryAddress.hexEip55; final acc = account ?? ethAccount.hexEip55; resume(); @@ -210,6 +211,7 @@ class ProfileLogic { _accountBackupDBService.accounts.update(DBAccount( alias: alias, address: ethAccount, + accountFactoryAddress: EthereumAddress.fromHex(accountFactoryAddress), name: profile.name, username: profile.username, privateKey: null, @@ -325,6 +327,7 @@ class ProfileLogic { DBAccount( alias: _wallet.alias!, address: EthereumAddress.fromHex(newProfile.account), + accountFactoryAddress: _wallet.accountFactoryAddress, name: newProfile.name, username: newProfile.username, privateKey: null, @@ -407,6 +410,7 @@ class ProfileLogic { DBAccount( alias: _wallet.alias!, address: EthereumAddress.fromHex(newProfile.account), + accountFactoryAddress: _wallet.accountFactoryAddress, name: newProfile.name, username: newProfile.username, privateKey: null, @@ -471,6 +475,7 @@ class ProfileLogic { final address = _wallet.account.hexEip55; final alias = _wallet.alias ?? ''; + final accountFactoryAddress = _wallet.accountFactoryAddress.hexEip55; final account = await _accountBackupDBService.accounts .get(EthereumAddress.fromHex(address), alias); @@ -554,6 +559,7 @@ class ProfileLogic { DBAccount( alias: alias, address: EthereumAddress.fromHex(address), + accountFactoryAddress: EthereumAddress.fromHex(accountFactoryAddress), name: newProfile.name, username: newProfile.username, profile: newProfile, diff --git a/lib/state/profiles/logic.dart b/lib/state/profiles/logic.dart index febe6767..23e983de 100644 --- a/lib/state/profiles/logic.dart +++ b/lib/state/profiles/logic.dart @@ -232,6 +232,7 @@ class ProfilesLogic extends WidgetsBindingObserver { DBAccount( alias: account.alias, address: account.address, + accountFactoryAddress: account.accountFactoryAddress, name: updatedProfile.name, username: updatedProfile.username, profile: updatedProfile, diff --git a/lib/state/wallet/logic.dart b/lib/state/wallet/logic.dart index 43f090dc..382c5258 100644 --- a/lib/state/wallet/logic.dart +++ b/lib/state/wallet/logic.dart @@ -8,6 +8,7 @@ import 'package:citizenwallet/services/cache/contacts.dart'; import 'package:citizenwallet/services/config/config.dart'; import 'package:citizenwallet/services/config/service.dart'; import 'package:citizenwallet/services/db/account/db.dart'; +import 'package:citizenwallet/services/db/app/communities.dart'; import 'package:citizenwallet/services/db/backup/accounts.dart'; import 'package:citizenwallet/services/db/app/db.dart'; import 'package:citizenwallet/services/db/account/transactions.dart'; @@ -373,6 +374,7 @@ class WalletLogic extends WidgetsBindingObserver { await _wallet.init( dbWallet.address, + dbWallet.accountFactoryAddress, dbWallet.privateKey!, nativeCurrency, communityConfig, @@ -390,17 +392,7 @@ class WalletLogic extends WidgetsBindingObserver { ContactsCache().init(_accountDBService); - _config - .isCommunityOnline( - communityConfig.chains[token.chainId.toString()]!.node.url) - .then((isOnline) { - communityConfig.online = isOnline; - - _state.setWalletConfig(communityConfig); - - _appDBService.communities - .updateOnlineStatus(communityConfig.community.alias, isOnline); - }); + updateWalletConfigFromRemote(); _state.setWallet( CWWallet( @@ -452,8 +444,6 @@ class WalletLogic extends WidgetsBindingObserver { final credentials = EthPrivateKey.createRandom(Random.secure()); - // final config = await _config.getConfig(alias); - final community = await _appDBService.communities.get(alias); if (community == null) { @@ -486,6 +476,8 @@ class WalletLogic extends WidgetsBindingObserver { privateKey: credentials, name: 'New ${token.symbol} Account', alias: communityConfig.community.alias, + accountFactoryAddress: EthereumAddress.fromHex( + communityConfig.community.primaryAccountFactory.address), )); _theme.changeTheme(communityConfig.community.theme); @@ -553,6 +545,7 @@ class WalletLogic extends WidgetsBindingObserver { privateKey: credentials, name: name, alias: communityConfig.community.alias, + accountFactoryAddress: EthereumAddress.fromHex(communityConfig.community.primaryAccountFactory.address), )); _theme.changeTheme(communityConfig.community.theme); @@ -582,6 +575,7 @@ class WalletLogic extends WidgetsBindingObserver { privateKey: dbWallet.privateKey, name: name, alias: dbWallet.alias, + accountFactoryAddress: dbWallet.accountFactoryAddress, )); loadDBWallets(); @@ -1103,7 +1097,8 @@ class WalletLogic extends WidgetsBindingObserver { final trimmedAmount = amount.trim(); if (trimmedAmount.endsWith(',') || trimmedAmount.endsWith('.')) { // Remove trailing separator and validate the partial amount - final withoutTrailing = trimmedAmount.substring(0, trimmedAmount.length - 1); + final withoutTrailing = + trimmedAmount.substring(0, trimmedAmount.length - 1); if (withoutTrailing.isEmpty) { // Just "," or "." - treat as empty (not invalid, but also not valid) return false; @@ -1118,7 +1113,7 @@ class WalletLogic extends WidgetsBindingObserver { balanceRaw, decimals: _wallet.currency.decimals, )); - + // Parse the amount as a double in human-readable format // Handle both comma and dot as decimal separators final normalizedAmount = amount.replaceAll(',', '.'); @@ -1726,7 +1721,7 @@ class WalletLogic extends WidgetsBindingObserver { Future updateAmount({bool unlimited = false}) async { // Fetch current balance before validating to ensure we check against the latest balance await updateBalance(); - + _state.setHasAmount( _amountController.text.isNotEmpty, isInvalidAmount(_amountController.value.text, unlimited: unlimited), @@ -2144,6 +2139,53 @@ class WalletLogic extends WidgetsBindingObserver { cleanupWalletService(); } + Future updateWalletConfigFromRemote() async { + try { + if (_wallet.alias == null) { + return; + } + + final community = await _appDBService.communities.get(_wallet.alias!); + + if (community == null) { + return; + } + + Config communityConfig = Config.fromJson(community.config); + + final remoteConfigUrl = communityConfig.configLocation; + + if (remoteConfigUrl.isEmpty) { + return; + } + + final remoteConfig = await _config.getRemoteConfig(remoteConfigUrl); + + if (remoteConfig == null) { + return; + } + + // Update the wallet config with the remote config + _state.setWalletConfig(remoteConfig); + + final token = remoteConfig.getPrimaryToken(); + + remoteConfig.online = await _config.isCommunityOnline( + remoteConfig.chains[token.chainId.toString()]!.node.url); + + _state.setWalletConfig(remoteConfig); + + // Update the database with the new config + await _appDBService.communities.upsert( + [DBCommunity.fromConfig(remoteConfig)], + ); + debugPrint('Remote config updated'); + } catch (e, s) { + debugPrint('Error updating remote config: $e'); + debugPrint('Stacktrace: $s'); + } + } + @override Future didChangeAppLifecycleState(AppLifecycleState state) async { switch (state) { @@ -2156,24 +2198,7 @@ class WalletLogic extends WidgetsBindingObserver { } await updateBalance(); - - final community = await _appDBService.communities.get(_wallet.alias!); - - if (community == null) { - return; - } - - Config communityConfig = Config.fromJson(community.config); - - final token = communityConfig.getPrimaryToken(); - - communityConfig.online = await _config.isCommunityOnline( - communityConfig.chains[token.chainId.toString()]!.node.url); - - await _appDBService.communities.updateOnlineStatus( - communityConfig.community.alias, communityConfig.online); - - _state.setWalletConfig(communityConfig); + await updateWalletConfigFromRemote(); break; default: diff --git a/pubspec.lock b/pubspec.lock index f7d21d5b..421acb2c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -69,10 +69,10 @@ packages: dependency: "direct main" description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.12.0" audio_in_app: dependency: "direct main" description: @@ -161,6 +161,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + buffer: + dependency: transitive + description: + name: buffer + sha256: "389da2ec2c16283c8787e0adaede82b1842102f8c8aae2f49003a766c5c6b3d1" + url: "https://pub.dev" + source: hosted + version: "1.2.3" cached_network_image: dependency: "direct main" description: @@ -213,10 +221,10 @@ packages: dependency: transitive description: name: checked_yaml - sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.0.3" cli_config: dependency: transitive description: @@ -374,10 +382,10 @@ packages: dependency: transitive description: name: dev_build - sha256: "1d9aa167c05cbe4be9fbaf863c76dcee9bec302fb861270672beb6d6be0bc8f4" + sha256: fda8a54458b2a873a84e0cd1513f4323a1fb0599ed5455245359bc0398bad9ee url: "https://pub.dev" source: hosted - version: "1.1.3+1" + version: "1.1.2+11" ed25519_edwards: dependency: transitive description: @@ -410,6 +418,22 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.3" + equatable: + dependency: transitive + description: + name: equatable + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + url: "https://pub.dev" + source: hosted + version: "2.0.7" + eth_sig_util: + dependency: transitive + description: + name: eth_sig_util + sha256: "20fdc5ce3864e70e5ade1c1cd03cce4ef01018db00adab107303f9055d26b01a" + url: "https://pub.dev" + source: hosted + version: "0.0.9" event: dependency: transitive description: @@ -430,10 +454,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" url: "https://pub.dev" source: hosted - version: "1.3.3" + version: "1.3.2" ffi: dependency: transitive description: @@ -632,10 +656,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "306f0596590e077338312f38837f595c04f28d6cdeeac392d3d74df2f0003687" + sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476 url: "https://pub.dev" source: hosted - version: "2.0.32" + version: "2.0.31" flutter_secure_storage: dependency: "direct main" description: @@ -706,10 +730,10 @@ packages: dependency: transitive description: name: freezed_annotation - sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" + sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "2.4.4" frontend_server_client: dependency: transitive description: @@ -874,10 +898,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.19.0" io: dependency: transitive description: @@ -914,26 +938,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec url: "https://pub.dev" source: hosted - version: "11.0.2" + version: "10.0.8" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.10" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.1" lints: dependency: transitive description: @@ -962,10 +986,10 @@ packages: dependency: "direct main" description: name: lottie - sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95" + sha256: c5fa04a80a620066c15cf19cc44773e19e9b38e989ff23ea32e5903ef1015950 url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.3.1" markdown: dependency: transitive description: @@ -1138,18 +1162,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16 + sha256: "3b4c1fc3aa55ddc9cd4aa6759984330d5c8e66aa7702a6223c61540dc6380c37" url: "https://pub.dev" source: hosted - version: "2.2.20" + version: "2.2.19" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738 + sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" url: "https://pub.dev" source: hosted - version: "2.4.3" + version: "2.4.2" path_provider_linux: dependency: transitive description: @@ -1178,10 +1202,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "6.1.0" platform: dependency: transitive description: @@ -1274,26 +1298,34 @@ packages: dependency: transitive description: name: reown_core - sha256: "8d5d14b4e8d008b09ec9db964ab8913b4fc17000d666eb1fece20a80a4b5e37a" + sha256: "37e8bd16263400856592b58331ec61665bcc8814d4a2a1801a7f12caf3c4673d" url: "https://pub.dev" source: hosted - version: "1.3.6" + version: "1.2.0" reown_sign: dependency: transitive description: name: reown_sign - sha256: c2fec55ed3d0042d0802c80d7fc36f9b1937eac6ef9c2907dae3b8146188cffa + sha256: ae2e171b93ddaae2ce7db18a66647afc9680cf55f49e88d49a3c3df5d1eb2cde url: "https://pub.dev" source: hosted - version: "1.3.7" + version: "1.2.0" reown_walletkit: dependency: "direct main" description: name: reown_walletkit - sha256: f96cc9f6e264138b3411fd1635e06d437d5912d7a21ef28af21974e2680dfd70 + sha256: b779e4914c9299edea80a849773fc08ddd5e44549bf53a2fd26cac4a59f5c99c + url: "https://pub.dev" + source: hosted + version: "1.2.0" + reown_yttrium: + dependency: transitive + description: + name: reown_yttrium + sha256: e59d9e8dbad8e2c420c201719da12bca528c38ecab9571364d5b6d18715ce773 url: "https://pub.dev" source: hosted - version: "1.3.7" + version: "0.0.1" rxdart: dependency: "direct main" description: @@ -1338,18 +1370,18 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: "34266009473bf71d748912da4bf62d439185226c03e01e2d9687bc65bbfcb713" + sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e url: "https://pub.dev" source: hosted - version: "2.4.15" + version: "2.4.13" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "1c33a907142607c40a7542768ec9badfd16293bac51da3a4482623d15845f88b" + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" url: "https://pub.dev" source: hosted - version: "2.5.5" + version: "2.5.4" shared_preferences_linux: dependency: transitive description: @@ -1472,18 +1504,18 @@ packages: dependency: transitive description: name: sqflite_android - sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88 + sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" url: "https://pub.dev" source: hosted - version: "2.4.2+2" + version: "2.4.1" sqflite_common: dependency: "direct main" description: name: sqflite_common - sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" + sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b" url: "https://pub.dev" source: hosted - version: "2.5.6" + version: "2.5.5" sqflite_common_ffi: dependency: transitive description: @@ -1496,10 +1528,10 @@ packages: dependency: "direct main" description: name: sqflite_common_ffi_web - sha256: "793c1ff5b0c95ac618e7731e209db99e96abff59ad3432a3c91bd2b1454a00d5" + sha256: "983cf7b33b16e6bc086c8e09f6a1fae69d34cdb167d7acaf64cbd3515942d4e6" url: "https://pub.dev" source: hosted - version: "1.0.1+2" + version: "1.0.0" sqflite_darwin: dependency: transitive description: @@ -1560,10 +1592,10 @@ packages: dependency: transitive description: name: synchronized - sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" url: "https://pub.dev" source: hosted - version: "3.4.0" + version: "3.3.1" term_glyph: dependency: transitive description: @@ -1576,26 +1608,26 @@ packages: dependency: transitive description: name: test - sha256: "65e29d831719be0591f7b3b1a32a3cda258ec98c58c7b25f7b84241bc31215bb" + sha256: "301b213cd241ca982e9ba50266bd3f5bd1ea33f1455554c5abb85d1be0e2d87e" url: "https://pub.dev" source: hosted - version: "1.26.2" + version: "1.25.15" test_api: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.4" test_core: dependency: transitive description: name: test_core - sha256: "80bf5a02b60af04b09e14f6fe68b921aad119493e26e490deaca5993fef1b05a" + sha256: "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa" url: "https://pub.dev" source: hosted - version: "0.6.11" + version: "0.6.8" timeago: dependency: "direct main" description: @@ -1640,18 +1672,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9" + sha256: "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e" url: "https://pub.dev" source: hosted - version: "6.3.24" + version: "6.3.20" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "6b63f1441e4f653ae799166a72b50b1767321ecc263a57aadf825a7a2a5477d9" + sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 url: "https://pub.dev" source: hosted - version: "6.3.5" + version: "6.3.4" url_launcher_linux: dependency: transitive description: @@ -1664,10 +1696,10 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: "8262208506252a3ed4ff5c0dc1e973d2c0e0ef337d0a074d35634da5d44397c9" + sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f url: "https://pub.dev" source: hosted - version: "3.2.4" + version: "3.2.3" url_launcher_platform_interface: dependency: transitive description: @@ -1736,18 +1768,18 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" url: "https://pub.dev" source: hosted - version: "15.0.2" + version: "14.3.1" wallet: dependency: transitive description: @@ -1808,10 +1840,10 @@ packages: dependency: transitive description: name: win32 - sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba" url: "https://pub.dev" source: hosted - version: "5.15.0" + version: "5.13.0" x25519: dependency: transitive description: @@ -1832,10 +1864,10 @@ packages: dependency: transitive description: name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.6.1" + version: "6.5.0" yaml: dependency: transitive description: @@ -1845,5 +1877,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.35.0" + dart: ">=3.7.2 <4.0.0" + flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index 82726d72..b09eb5fa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -131,6 +131,9 @@ flutter: - assets/config/v4/communities.json - assets/config/v4/communities.test.json - assets/config/v4/debug.json + - assets/config/v5/communities.json + - assets/config/v5/communities.test.json + - assets/config/v5/debug.json - assets/icons/switch_accounts.svg - assets/config/v3/communities.json - assets/config/v3/communities.test.json diff --git a/test/services/config/config_v5_test.dart b/test/services/config/config_v5_test.dart new file mode 100644 index 00000000..5f1bf230 --- /dev/null +++ b/test/services/config/config_v5_test.dart @@ -0,0 +1,613 @@ +import 'dart:io'; +import 'dart:convert'; +import 'package:citizenwallet/services/config/config.dart'; +import 'package:test/test.dart'; + +const Map> communitiesWithMultipleAccountFactories = { + 'wallet.pay.brussels': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE', + ], + 'gratitude': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD' + ], + 'bread': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9' + ], + 'wallet.commonshub.brussels': [ + '0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'wallet.regensunite.earth': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0x9406Cc6185a346906296840746125a0E44976454' + ], + 'gt.celo': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD' + ], + 'ceur.celo': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098' + ], + 'eure.polygon': [ + '0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'app': [ + '0x270758454C012A1f51428b68aE473D728CCdFe88', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'usdc.base': [ + '0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'wallet.oak.community': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0x9406Cc6185a346906296840746125a0E44976454' + ], + 'sbc.polygon': [ + '0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'zinne': [ + '0x11af2639817692D2b805BcE0e1e405E530B20006', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'timebank.regensunite.earth': [ + '0x39b77d77f7677997871b304094a05295eb71e240', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'moos': [ + '0x671f0662de72268d0f3966Fb62dFc6ee6389e244', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'selcoupdepouce': [ + '0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'cit.celo': [ + '0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185' + ], + 'wallet.wolugo.be': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0x8474153A00C959f2cB64852949954DBC68415Bb3' + ], + 'wtc.celo': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xE79E19594A749330036280c685E2719d58d99052' + ], + 'testnet-ethldn': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xc1654087C580f868F08E34cd1c01eDB1d3673b82' + ], + 'celo-c.citizenwallet.xyz': [ + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185', + '0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA' + ], +}; + +const Map> communityRpcUrls = { + 'ctzn': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0x3A3E25871c5C6C84D5f397829FF316a37F7FD596', + }, + 'wallet.pay.brussels': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://engine.pay.brussels/v1/rpc/0xE69C843898E21C0E95eA7DD310cD850AAc0aB897', + '0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE': + 'https://engine.pay.brussels/v1/rpc/0xcA1B9EC1117340818C1c1fdd1B48Ea79E57C140F', + }, + 'gratitude': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0xF05ba2641b31AF70c2678e3324eD8b9C53093FbE', + '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8' + }, + 'bread': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://100.engine.citizenwallet.xyz/v1/rpc/0x5987e57e85014B5A56C880313580346c20a5d1c1', + '0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9': + 'https://100.engine.citizenwallet.xyz/v1/rpc/0xbE2Cb3358aa14621134e923B68b8429315368E32' + }, + 'wallet.commonshub.brussels': { + '0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x4E127A1DAa66568B4a91E8c5615120a6Ea5442E3', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x4860C0f127500F0cbF4a5Bd797cBb5aA50Eb0FbA' + }, + 'wallet.regensunite.earth': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0x250711045d58b6310f0635C7D110BFe663cE1da5', + '0x9406Cc6185a346906296840746125a0E44976454': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0x250711045d58b6310f0635C7D110BFe663cE1da5' + }, + 'gt.celo': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8', + '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x8dd43eE72f6A816b8eB0411B712D96cDd95246d8' + }, + 'ceur.celo': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0xedbEA8c0F25B34510149EaD4f72867B0d3D2264F', + '0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0xedbEA8c0F25B34510149EaD4f72867B0d3D2264F' + }, + 'eure.polygon': { + '0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0xB2cb6b75C2357Ca94dBdF58897E468E45fAC83Ec', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0xB2cb6b75C2357Ca94dBdF58897E468E45fAC83Ec' + }, + 'app': { + '0x270758454C012A1f51428b68aE473D728CCdFe88': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0xB5D1C0167E6325466E2918e9fda8cc41384C0291', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0xB5D1C0167E6325466E2918e9fda8cc41384C0291' + }, + 'usdc.base': { + '0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99': + 'https://8453.engine.citizenwallet.xyz/v1/rpc/0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://8453.engine.citizenwallet.xyz/v1/rpc/0xA63DFccB8a39a3DFE4479b33190b12019Ee594E7' + }, + 'wallet.oak.community': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://8453.engine.citizenwallet.xyz/v1/rpc/0x123', + '0x9406Cc6185a346906296840746125a0E44976454': + 'https://8453.engine.citizenwallet.xyz/v1/rpc/0x123' + }, + 'sbc.polygon': { + '0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0x123', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0x123' + }, + 'zinne': { + '0x11af2639817692D2b805BcE0e1e405E530B20006': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0xBb796D122Ec1aBDeD081D50B06a072f981c7E62b', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://137.engine.citizenwallet.xyz/v1/rpc/0xBb796D122Ec1aBDeD081D50B06a072f981c7E62b' + }, + 'timebank.regensunite.earth': { + '0x39b77d77f7677997871b304094a05295eb71e240': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0xe45858bf63176595c2920822581917c7C705a12f', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0xe45858bf63176595c2920822581917c7C705a12f' + }, + 'moos': { + '0x671f0662de72268d0f3966Fb62dFc6ee6389e244': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x55E519bfD63c7152D9F7B88Acd712A37F0BEC482', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x55E519bfD63c7152D9F7B88Acd712A37F0BEC482' + }, + 'selcoupdepouce': { + '0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x635032605337aB36A46D767905108e67EE687a72', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x635032605337aB36A46D767905108e67EE687a72' + }, + 'cit.celo': { + '0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x452F7ff3e55fe29f481841985dE7f4939FD645fa', + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x452F7ff3e55fe29f481841985dE7f4939FD645fa' + }, + 'wallet.wolugo.be': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0xF2EFEC3cBFaDE0bB6108620cbF7Cc608d27DCF3c', + '0x8474153A00C959f2cB64852949954DBC68415Bb3': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0xF2EFEC3cBFaDE0bB6108620cbF7Cc608d27DCF3c' + }, + 'wtc.celo': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x3fefC19674f3F6E43B1dFf1861E07c303B9eAAc9', + '0xE79E19594A749330036280c685E2719d58d99052': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x3fefC19674f3F6E43B1dFf1861E07c303B9eAAc9' + }, + 'testnet-ethldn': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://84532.engine.citizenwallet.xyz/v1/rpc/0x389182aCCeE26D953d5188BF4b92c49339DcC9FC', + '0xc1654087C580f868F08E34cd1c01eDB1d3673b82': + 'https://84532.engine.citizenwallet.xyz/v1/rpc/0x389182aCCeE26D953d5188BF4b92c49339DcC9FC' + }, + 'celo-c.citizenwallet.xyz': { + '0x7cC54D54bBFc65d1f0af7ACee5e4042654AF8185': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x7f4011845Ea914b6cefc60629e1e00600c972c75', + '0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA': + 'https://42220.engine.citizenwallet.xyz/v1/rpc/0x7f4011845Ea914b6cefc60629e1e00600c972c75' + }, +}; + +void main() { + late List configs; + + setUpAll(() async { + // Load and parse JSON file + final jsonString = + await File('assets/config/v5/communities.json').readAsString(); + final jsonList = jsonDecode(jsonString) as List; + configs = jsonList + .map((json) => Config.fromJson(json as Map)) + .toList(); + }); + + group('V5 Config Parsing', () { + test('loads all configs successfully', () { + expect(configs.length, greaterThan(0)); + print('Loaded ${configs.length} configs'); + }); + + test('all configs have valid community data', () { + for (final config in configs) { + expect(config.community.name, isNotEmpty, + reason: 'Community name should not be empty'); + expect(config.community.alias, isNotEmpty, + reason: 'Community alias should not be empty'); + expect(config.community.description, isNotEmpty, + reason: 'Community description should not be empty'); + expect(config.community.url, isNotEmpty, + reason: 'Community URL should not be empty'); + expect(config.community.logo, isNotEmpty, + reason: 'Community logo should not be empty'); + } + }); + + test('all configs have required maps populated', () { + for (final config in configs) { + expect(config.tokens, isNotEmpty, + reason: + 'Config for ${config.community.alias} should have at least one token'); + expect(config.accounts, isNotEmpty, + reason: + 'Config for ${config.community.alias} should have at least one account'); + expect(config.chains, isNotEmpty, + reason: + 'Config for ${config.community.alias} should have at least one chain'); + } + }); + + test('all configs have valid scan configuration', () { + for (final config in configs) { + expect(config.scan.url, isNotEmpty, + reason: + 'Scan URL should not be empty for ${config.community.alias}'); + expect(config.scan.name, isNotEmpty, + reason: + 'Scan name should not be empty for ${config.community.alias}'); + } + }); + + test('all configs have valid IPFS configuration', () { + for (final config in configs) { + expect(config.ipfs.url, isNotEmpty, + reason: + 'IPFS URL should not be empty for ${config.community.alias}'); + } + }); + + test('all configs have valid version field', () { + for (final config in configs) { + expect(config.version, greaterThanOrEqualTo(4), + reason: + 'Version should be 4 or higher for ${config.community.alias}'); + expect(config.version, lessThanOrEqualTo(5), + reason: + 'Version should be 5 or lower for ${config.community.alias}'); + } + }); + + test('all configs have valid config location', () { + for (final config in configs) { + expect(config.configLocation, isNotEmpty, + reason: + 'Config location should not be empty for ${config.community.alias}'); + expect(config.configLocation, startsWith('https://'), + reason: + 'Config location should be HTTPS URL for ${config.community.alias}'); + } + }); + + test('primary token exists in tokens map', () { + for (final config in configs) { + final primaryTokenKey = config.community.primaryToken.fullAddress; + expect(config.tokens.containsKey(primaryTokenKey), isTrue, + reason: + 'Primary token should exist in tokens map for ${config.community.alias}'); + } + }); + + test('primary account factory exists in accounts map', () { + for (final config in configs) { + final primaryAccountKey = + config.community.primaryAccountFactory.fullAddress; + expect(config.accounts.containsKey(primaryAccountKey), isTrue, + reason: + 'Primary account factory should exist in accounts map for ${config.community.alias}'); + } + }); + + test('primary card manager exists in cards map if specified', () { + for (final config in configs) { + if (config.community.primaryCardManager != null) { + final primaryCardKey = + config.community.primaryCardManager!.fullAddress; + expect(config.cards?.containsKey(primaryCardKey) ?? false, isTrue, + reason: + 'Primary card manager should exist in cards map for ${config.community.alias}'); + } + } + }); + + test('chain IDs match between community and chains map', () { + for (final config in configs) { + final primaryChainId = config.community.primaryToken.chainId.toString(); + expect(config.chains.containsKey(primaryChainId), isTrue, + reason: + 'Primary chain ID should exist in chains map for ${config.community.alias}'); + } + }); + + test('getPrimaryToken returns valid token', () { + for (final config in configs) { + final token = config.getPrimaryToken(); + expect(token.name, isNotEmpty, + reason: + 'Token name should not be empty for ${config.community.alias}'); + expect(token.symbol, isNotEmpty, + reason: + 'Token symbol should not be empty for ${config.community.alias}'); + expect(token.decimals, greaterThanOrEqualTo(0), + reason: + 'Token decimals should be non-negative for ${config.community.alias}'); + } + }); + + test('getPrimaryAccountAbstractionConfig returns valid config', () { + for (final config in configs) { + final aaConfig = config.getAccountAbstractionConfig( + accountFactoryAddress: + config.community.primaryAccountFactory.address); + expect(aaConfig.entrypointAddress, isNotEmpty, + reason: + 'Entrypoint address should not be empty for ${config.community.alias}'); + expect(aaConfig.accountFactoryAddress, isNotEmpty, + reason: + 'Account factory address should not be empty for ${config.community.alias}'); + expect(aaConfig.paymasterType, isNotEmpty, + reason: + 'Paymaster type should not be empty for ${config.community.alias}'); + } + }); + + test('plugins list is properly parsed', () { + for (final config in configs) { + if (config.plugins != null && config.plugins!.isNotEmpty) { + for (final plugin in config.plugins!) { + expect(plugin.name, isNotEmpty, + reason: + 'Plugin name should not be empty for ${config.community.alias}'); + expect(plugin.url, isNotEmpty, + reason: + 'Plugin URL should not be empty for ${config.community.alias}'); + } + } + } + }); + + test('custom domain matches alias pattern when present', () { + for (final config in configs) { + if (config.community.customDomain != null) { + // Custom domain should typically match or be related to the alias + expect(config.community.customDomain, isNotEmpty, + reason: + 'Custom domain should not be empty when specified for ${config.community.alias}'); + } + } + }); + + test('wallet URL generation works correctly', () { + const deepLinkBaseUrl = 'https://app.citizenwallet.xyz'; + for (final config in configs) { + final walletUrl = config.community.walletUrl(deepLinkBaseUrl); + expect(walletUrl, startsWith(deepLinkBaseUrl), + reason: + 'Wallet URL should start with base URL for ${config.community.alias}'); + expect(walletUrl, contains('alias=${config.community.alias}'), + reason: + 'Wallet URL should contain alias parameter for ${config.community.alias}'); + } + }); + }); + + group('getAccountAbstractionConfig', () { + test('returns primary config when no address provided', () { + for (final config in configs) { + final aaConfig = config.getAccountAbstractionConfig( + accountFactoryAddress: + config.community.primaryAccountFactory.address); + expect(aaConfig, isA(), + reason: + 'Should return ERC4337Config for ${config.community.alias}'); + expect(aaConfig.accountFactoryAddress, + config.community.primaryAccountFactory.address, + reason: + 'Should return primary account factory address for ${config.community.alias}'); + } + }); + + test('throws exception when empty address provided', () { + final config = configs.first; + expect( + () => config.getAccountAbstractionConfig(accountFactoryAddress: ''), + throwsException, + reason: + 'Should throw exception when empty account factory address is provided', + ); + }); + + test( + 'returns correct config for each account factory in multi-factory communities', + () { + for (final config in configs) { + final alias = config.community.alias; + if (communitiesWithMultipleAccountFactories.containsKey(alias)) { + final factories = communitiesWithMultipleAccountFactories[alias]!; + for (final factoryAddress in factories) { + final aaConfig = config.getAccountAbstractionConfig( + accountFactoryAddress: factoryAddress); + expect(aaConfig, isA(), + reason: + 'Should return ERC4337Config for $alias with factory $factoryAddress'); + expect(aaConfig.accountFactoryAddress, factoryAddress, + reason: + 'Should return correct account factory address for $alias'); + } + } + } + }); + + test('throws exception for non-existent account factory address', () { + final config = configs.first; + expect( + () => config.getAccountAbstractionConfig( + accountFactoryAddress: '0xNonExistentAddress'), + throwsException, + reason: + 'Should throw exception for non-existent account factory address', + ); + }); + + test('all account factories in map exist in their respective configs', () { + for (final config in configs) { + final alias = config.community.alias; + if (communitiesWithMultipleAccountFactories.containsKey(alias)) { + final factories = communitiesWithMultipleAccountFactories[alias]!; + for (final factoryAddress in factories) { + final chainId = config.community.primaryToken.chainId; + final fullAddress = '$chainId:$factoryAddress'; + expect(config.accounts.containsKey(fullAddress), isTrue, + reason: + 'Account factory $factoryAddress should exist in accounts map for $alias'); + } + } + } + }); + }); + + group('getRpcUrl', () { + test('returns correct URL for primary account factory', () { + for (final config in configs) { + final alias = config.community.alias; + + // Skip if no expected RPC URL defined for this community + if (!communityRpcUrls.containsKey(alias)) { + continue; + } + + final chainId = config.community.primaryToken.chainId.toString(); + final primaryAccountFactory = + config.community.primaryAccountFactory.address; + final expectedUrls = communityRpcUrls[alias]!; + + // Get the expected URL for the primary account factory + final expectedUrl = expectedUrls[primaryAccountFactory]; + + if (expectedUrl != null) { + final actualUrl = config.getRpcUrl( + chainId: chainId, accountFactoryAddress: primaryAccountFactory); + expect(actualUrl, equals(expectedUrl), + reason: 'RPC URL mismatch for $alias (primary account factory)'); + } + } + }); + + test('returns correct URL for specific account factory', () { + for (final config in configs) { + final alias = config.community.alias; + + // Skip if no expected RPC URLs defined for this community + if (!communityRpcUrls.containsKey(alias)) { + continue; + } + + final chainId = config.community.primaryToken.chainId.toString(); + final expectedUrls = communityRpcUrls[alias]!; + + // Test each account factory address + for (final accountFactory in expectedUrls.keys) { + final expectedUrl = expectedUrls[accountFactory]!; + final actualUrl = config.getRpcUrl( + chainId: chainId, + accountFactoryAddress: accountFactory, + ); + + expect(actualUrl, equals(expectedUrl), + reason: + 'RPC URL mismatch for $alias with account factory $accountFactory'); + } + } + }); + + test('works for communities with multiple account factories', () { + for (final alias in communitiesWithMultipleAccountFactories.keys) { + final config = configs.firstWhere((c) => c.community.alias == alias); + final accountFactories = + communitiesWithMultipleAccountFactories[alias]!; + final chainId = config.community.primaryToken.chainId.toString(); + + expect(accountFactories.length, greaterThan(1), + reason: '$alias should have multiple account factories'); + + // Verify each account factory returns a different RPC URL + final urls = {}; + for (final accountFactory in accountFactories) { + final url = config.getRpcUrl( + chainId: chainId, + accountFactoryAddress: accountFactory, + ); + urls.add(url); + } + + // All URLs should be valid and non-empty + for (final url in urls) { + expect(url, isNotEmpty); + expect(url, startsWith('https://')); + expect(url, contains('/v1/rpc/')); + } + } + }); + + test('throws exception for invalid chain ID', () { + final config = configs.first; + + expect( + () => config.getRpcUrl( + chainId: '99999', + accountFactoryAddress: + config.community.primaryAccountFactory.address), + throwsException, + reason: 'Should throw exception for non-existent chain ID', + ); + }); + + test('throws exception for non-existent account factory', () { + final config = configs.first; + final chainId = config.community.primaryToken.chainId.toString(); + + expect( + () => config.getRpcUrl( + chainId: chainId, + accountFactoryAddress: '0xNonExistentAddress', + ), + throwsException, + reason: + 'Should throw exception for non-existent account factory address', + ); + }); + }); +} diff --git a/test/services/config/utils_test.dart b/test/services/config/utils_test.dart new file mode 100644 index 00000000..5fd3701e --- /dev/null +++ b/test/services/config/utils_test.dart @@ -0,0 +1,146 @@ +import 'package:citizenwallet/services/config/utils.dart'; +import 'package:test/test.dart'; + +/// Expected outcomes map for testing getAccountFactoryAddressByAlias +/// Covers all four logic branches: +/// 1. Hardcoded overrides (gratitude, bread, wallet.commonshub.brussels, wallet.sfluv.org) +/// 2. Safe factory redirection (old safe factory -> new safe factory) +/// 3. General fallback (return mapped address as-is) +/// 4. Unknown alias (return new safe factory as safety default) +const Map expectedOutcomes = { + // 1. Hardcoded Overrides - these should return their ORIGINAL addresses + 'gratitude': '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD', + 'bread': '0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9', + 'wallet.commonshub.brussels': '0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87', + 'wallet.sfluv.org': '0x5e987a6c4bb4239d498E78c34e986acf29c81E8e', + + // 2. Safe Factory Redirection - old safe factory should redirect to new safe factory + 'ctzn': newSafeFactory, + 'txirrin': newSafeFactory, + 'boliviapay': newSafeFactory, + 'seldesalm': newSafeFactory, + 'my.techi.be': newSafeFactory, + 'wallet.kingfishersmedia.io': newSafeFactory, + + // 3. General Fallback - return mapped addresses as-is + 'wallet.berachain.sfluv.org': newSafeFactory, + 'laborhour': newSafeFactory, + 'rooted': newSafeFactory, + 'wallet.pay.brussels': '0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE', + 'wallet.regensunite.earth': '0x9406Cc6185a346906296840746125a0E44976454', + 'gt.celo': '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD', + 'ceur.celo': '0xdA529eBEd3D459dac9d9D3D45b8Cae2D5796c098', + 'eure.polygon': '0x5bA08d9fC7b90f79B2b856bdB09FC9EB32e83616', + 'app': '0x270758454C012A1f51428b68aE473D728CCdFe88', + 'usdc.base': '0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99', + 'wallet.oak.community': '0x9406Cc6185a346906296840746125a0E44976454', + 'sbc.polygon': '0x3Be13D9325C8C9174C3819d3d868D5D3aB8Fc8a5', + 'zinne': '0x11af2639817692D2b805BcE0e1e405E530B20006', + 'timebank.regensunite.earth': '0x39b77d77f7677997871b304094a05295eb71e240', + 'moos': '0x671f0662de72268d0f3966Fb62dFc6ee6389e244', + 'selcoupdepouce': '0x4Cc883b7E8E0BCB2e293703EF06426F9b4A5A284', + 'cit.celo': '0x0a9f4B7e7Ec393fF25dc9267289Be259Ec3FB970', + 'wallet.wolugo.be': '0x8474153A00C959f2cB64852949954DBC68415Bb3', + 'wtc.celo': '0xE79E19594A749330036280c685E2719d58d99052', + 'testnet-ethldn': '0xc1654087C580f868F08E34cd1c01eDB1d3673b82', + 'celo-c.citizenwallet.xyz': '0xcd8b1B9E760148c5026Bc5B0D56a5374e301FDcA', + + // 4. Unknown Alias - should return new safe factory as safety default + 'non-existent-alias': newSafeFactory, + 'unknown-community': newSafeFactory, + 'test-alias-not-in-map': newSafeFactory, +}; + +void main() { + group('getAccountFactoryAddressByAlias', () { + test('returns correct addresses for all test cases', () { + expectedOutcomes.forEach((alias, expectedAddress) { + final result = getAccountFactoryAddressByAlias(alias); + expect( + result, + expectedAddress, + reason: 'Failed for alias: $alias', + ); + }); + }); + + group('specific logic branch tests', () { + test('hardcoded overrides return original addresses', () { + // These four should return their original addresses, not redirected + expect( + getAccountFactoryAddressByAlias('gratitude'), + '0xAE6E18a9Cd26de5C8f89B886283Fc3f0bE5f04DD', + reason: 'gratitude should return its original address', + ); + expect( + getAccountFactoryAddressByAlias('bread'), + '0xAE76B1C6818c1DD81E20ccefD3e72B773068ABc9', + reason: 'bread should return its original address', + ); + expect( + getAccountFactoryAddressByAlias('wallet.commonshub.brussels'), + '0x307A9456C4057F7C7438a174EFf3f25fc0eA6e87', + reason: + 'wallet.commonshub.brussels should return its original address', + ); + expect( + getAccountFactoryAddressByAlias('wallet.sfluv.org'), + '0x5e987a6c4bb4239d498E78c34e986acf29c81E8e', + reason: 'wallet.sfluv.org should return its original address', + ); + }); + + test('old safe factory addresses are redirected to new safe factory', () { + // All these aliases map to old safe factory and should be redirected + final oldSafeFactoryAliases = [ + 'ctzn', + 'txirrin', + 'boliviapay', + 'seldesalm', + 'my.techi.be', + 'wallet.kingfishersmedia.io', + ]; + + for (final alias in oldSafeFactoryAliases) { + expect( + getAccountFactoryAddressByAlias(alias), + newSafeFactory, + reason: '$alias should be redirected to new safe factory', + ); + } + }); + + test('general fallback returns mapped addresses as-is', () { + // Sample of aliases that should return their mapped addresses unchanged + expect( + getAccountFactoryAddressByAlias('wallet.pay.brussels'), + '0xBABCf159c4e3186cf48e4a48bC0AeC17CF9d90FE', + ); + expect( + getAccountFactoryAddressByAlias('app'), + '0x270758454C012A1f51428b68aE473D728CCdFe88', + ); + expect( + getAccountFactoryAddressByAlias('usdc.base'), + '0x05e2Fb34b4548990F96B3ba422eA3EF49D5dAa99', + ); + }); + + test('unknown aliases return new safe factory as default', () { + // Test various unknown aliases + expect( + getAccountFactoryAddressByAlias('non-existent-alias'), + newSafeFactory, + ); + expect( + getAccountFactoryAddressByAlias('unknown-community'), + newSafeFactory, + ); + expect( + getAccountFactoryAddressByAlias('random-test-123'), + newSafeFactory, + ); + }); + }); + }); +}