| 1 | import "package:cake_wallet/utils/payment_request.dart"; |
| 2 | import "package:cw_core/erc20_token.dart"; |
| 3 | import "package:flutter_test/flutter_test.dart"; |
| 4 | |
| 5 | void main() { |
| 6 | group("PaymentRequest", () { |
| 7 | group("Ethereum URIs", () { |
| 8 | test("extract address and raw token amount from EIP681 Uri with contract", () { |
| 9 | final uri = Uri.parse( |
| 10 | "ethereum:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174@1/transfer?address=0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41&uint256=2000000000000000000", |
| 11 | ); |
| 12 | final paymentRequest = PaymentRequest.fromUri(uri); |
| 13 | |
| 14 | expect(paymentRequest.address, "0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41"); |
| 15 | expect(paymentRequest.amount, ""); |
| 16 | expect(paymentRequest.rawTokenAmount, "2000000000000000000"); |
| 17 | }); |
| 18 | |
| 19 | test("extract address and amount from EIP681 Uri", () { |
| 20 | final uri = Uri.parse( |
| 21 | "ethereum:0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41@1?value=2000000000000000000", |
| 22 | ); |
| 23 | final paymentRequest = PaymentRequest.fromUri(uri); |
| 24 | |
| 25 | expect(paymentRequest.address, "0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41"); |
| 26 | expect(paymentRequest.amount, "2"); |
| 27 | }); |
| 28 | |
| 29 | test("extract address and amount from Cake Style Uri", () { |
| 30 | final uri = Uri.parse("ethereum:0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41@1?amount=2.00"); |
| 31 | final paymentRequest = PaymentRequest.fromUri(uri); |
| 32 | |
| 33 | expect(paymentRequest.address, "0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41"); |
| 34 | expect(paymentRequest.amount, "2.00"); |
| 35 | }); |
| 36 | |
| 37 | test("extract address from EIP681 Uri with contract", () { |
| 38 | final uri = Uri.parse( |
| 39 | "ethereum:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174@1/transfer?address=0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41", |
| 40 | ); |
| 41 | final paymentRequest = PaymentRequest.fromUri(uri); |
| 42 | |
| 43 | expect(paymentRequest.address, "0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41"); |
| 44 | expect(paymentRequest.amount, ""); |
| 45 | }); |
| 46 | |
| 47 | test("extract address and raw token amount from EIP681 Uri with contract and no chainId", () { |
| 48 | final uri = Uri.parse( |
| 49 | "ethereum:0x1234567890abcdef1234567890abcdef12345678/transfer?address=0xabcdef1234567890abcdef1234567890abcdef12&uint256=1000000000000000000", |
| 50 | ); |
| 51 | final paymentRequest = PaymentRequest.fromUri(uri); |
| 52 | |
| 53 | expect(paymentRequest.address, "0xabcdef1234567890abcdef1234567890abcdef12"); |
| 54 | expect(paymentRequest.amount, ""); |
| 55 | expect(paymentRequest.rawTokenAmount, "1000000000000000000"); |
| 56 | }); |
| 57 | |
| 58 | test("extract address from minimal EIP681 Uri", () { |
| 59 | final uri = Uri.parse("ethereum:0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41"); |
| 60 | final paymentRequest = PaymentRequest.fromUri(uri); |
| 61 | |
| 62 | expect(paymentRequest.address, "0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41"); |
| 63 | expect(paymentRequest.amount, ""); |
| 64 | }); |
| 65 | }); |
| 66 | |
| 67 | group("resolveTokenAmount", () { |
| 68 | final usdt = Erc20Token( |
| 69 | name: "Tether", |
| 70 | symbol: "USDT", |
| 71 | contractAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7", |
| 72 | decimal: 6, |
| 73 | ); |
| 74 | final dai = Erc20Token( |
| 75 | name: "Dai", |
| 76 | symbol: "DAI", |
| 77 | contractAddress: "0x6B175474E89094C44Da98b954EedeAC495271d0F", |
| 78 | decimal: 18, |
| 79 | ); |
| 80 | |
| 81 | test("converts the raw uint256 using the token decimals", () { |
| 82 | final uri = Uri.parse( |
| 83 | "ethereum:0xdAC17F958D2ee523a2206206994597C13D831ec7@1/transfer?address=0xCfc1650da7C961FD82998e7e30ca5f699D0aBf41&uint256=1000000", |
| 84 | ); |
| 85 | final paymentRequest = PaymentRequest.fromUri(uri); |
| 86 | |
| 87 | expect(paymentRequest.resolveTokenAmount(usdt), "1"); |
| 88 | }); |
| 89 | |
| 90 | test("converts an 18 decimal raw amount unchanged", () { |
| 91 | final paymentRequest = |
| 92 | PaymentRequest("addr", "", "", "ethereum", null, rawTokenAmount: "1500000000000000000"); |
| 93 | |
| 94 | expect(paymentRequest.resolveTokenAmount(dai), "1.5"); |
| 95 | }); |
| 96 | |
| 97 | test("falls back to the legacy 18 decimal reading for implausibly large amounts", () { |
| 98 | final paymentRequest = PaymentRequest( |
| 99 | "addr", |
| 100 | "", |
| 101 | "", |
| 102 | "ethereum", |
| 103 | null, |
| 104 | rawTokenAmount: "50000000000000000000", |
| 105 | ); |
| 106 | |
| 107 | expect(paymentRequest.resolveTokenAmount(usdt), "50"); |
| 108 | }); |
| 109 | |
| 110 | test("prefers the decimal amount over the raw token amount", () { |
| 111 | final paymentRequest = |
| 112 | PaymentRequest("addr", "2.5", "", "ethereum", null, rawTokenAmount: "1000000"); |
| 113 | |
| 114 | expect(paymentRequest.resolveTokenAmount(usdt), "2.5"); |
| 115 | }); |
| 116 | |
| 117 | test("returns null when there is no amount at all", () { |
| 118 | final paymentRequest = PaymentRequest("addr", "", "", "ethereum", null); |
| 119 | |
| 120 | expect(paymentRequest.resolveTokenAmount(usdt), null); |
| 121 | }); |
| 122 | }); |
| 123 | }); |
| 124 | } |