mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-01 15:07:35 +02:00
* feat: nwc funding source * implement paid_invoices_stream, fix for unsettled invoices where settled_at is present but None * cancel pending_payments_lookup_task on cleanup * Rename subscription_timeout_task to timeout_task * ensure preimage is not None * Improve readability, return failed status on expiration in get_payment_status, ensure result_type is checked after error (some implementations might not set a result_type on error) * fetch account info when possible * workaround possible race condition on some nwc service providers, improve performance of fallback by using payment_hash from bolt11 invoice * fundle * make format * fix formatting * fix C901 `_on_message` is too complex (21 > 16) * format * fix lint * format * fix tests/wallets/test_nwc_wallets.py:80:11: C901 `run` is too complex (17 > 16) * fix padding * fix documentation for _verify_event method * refactoring and fixes * Split NWCWallet - NWCConnection * refactor class methods into helpers * update bundle * format * catch NWCError failure codes * format and fix * chore: bundle * add example * typos --------- Co-authored-by: Riccardo Balbo <riccardo0blb@gmail.com> Co-authored-by: benarc <ben@arc.wales> Co-authored-by: Pavol Rusnak <pavol@rusnak.io>
This commit is contained in:
571
tests/wallets/fixtures/json/fixtures_nwc.json
Normal file
571
tests/wallets/fixtures/json/fixtures_nwc.json
Normal file
@@ -0,0 +1,571 @@
|
||||
{
|
||||
"funding_sources": {
|
||||
"nwc": {
|
||||
"wallet_class": "NWCWallet",
|
||||
"settings": {
|
||||
"nwc_pairing_url": "nostr+walletconnect://be927be01ce2b3ab0fc33ffec6c6ab590381d7fc883a392d163d3966fc5840b3?relay=ws://127.0.0.1:8555&secret=d1b1d3b0f4a1fcba4c15094d34ff0569cae3c8c7af939b3473ccd564cce3bfa3"
|
||||
},
|
||||
"mock_settings": {
|
||||
"service_public_key": "be927be01ce2b3ab0fc33ffec6c6ab590381d7fc883a392d163d3966fc5840b3",
|
||||
"service_private_key": "ad6a224c9c2f2a7ac7181092348d99671a94f28974e331e0f0afe3bcdab72bed",
|
||||
"user_public_key": "bef38893a567e717110478cc5729f4bf881727f5a7d7859edad2b2b21ee81f7e",
|
||||
"user_private_key": "d1b1d3b0f4a1fcba4c15094d34ff0569cae3c8c7af939b3473ccd564cce3bfa3",
|
||||
"port": 8555,
|
||||
"supported_methods": [
|
||||
"get_balance",
|
||||
"make_invoice",
|
||||
"pay_invoice",
|
||||
"lookup_invoice"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"status": {
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"get_balance": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "success",
|
||||
"call_params": {},
|
||||
"expect": {
|
||||
"error_message": null,
|
||||
"balance_msat": 55000
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"get_balance": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "get_balance",
|
||||
"params": {}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "get_balance",
|
||||
"result": {
|
||||
"balance": 55000
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "error",
|
||||
"call_params": {},
|
||||
"expect": {
|
||||
"error_message": "TEST ERROR test-error",
|
||||
"balance_msat": 0
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"get_balance": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "get_balance",
|
||||
"params": {}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "get_balance",
|
||||
"error": {
|
||||
"code": "TEST ERROR",
|
||||
"message": "test-error"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"create_invoice": {
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"make_invoice": {}
|
||||
},
|
||||
"nwc-bad": {
|
||||
"make_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "success",
|
||||
"call_params": {
|
||||
"amount": 555,
|
||||
"memo": "Test Invoice",
|
||||
"label": "test-label"
|
||||
},
|
||||
"expect": {
|
||||
"error_message": null,
|
||||
"success": true,
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"payment_request": "lnbc5550n1pnq9jg3sp52rvwstvjcypjsaenzdh0h30jazvzsf8aaye0julprtth9kysxtuspp5e5s3z7felv4t9zrcc6wpn7ehvjl5yzewanzl5crljdl3jgeffyhqdq2f38xy6t5wvxqzjccqpjrzjq0yzeq76ney45hmjlnlpvu0nakzy2g35hqh0dujq8ujdpr2e42pf2rrs6vqpgcsqqqqqqqqqqqqqqeqqyg9qxpqysgqwftcx89k5pp28435pgxfl2vx3ksemzxccppw2j9yjn0ngr6ed7wj8ztc0d5kmt2mvzdlcgrludhz7jncd5l5l9w820hc4clpwhtqj3gq62g66n"
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"make_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "make_invoice",
|
||||
"params": {
|
||||
"amount": 555000,
|
||||
"description": "Test Invoice"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "make_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc5550n1pnq9jg3sp52rvwstvjcypjsaenzdh0h30jazvzsf8aaye0julprtth9kysxtuspp5e5s3z7felv4t9zrcc6wpn7ehvjl5yzewanzl5crljdl3jgeffyhqdq2f38xy6t5wvxqzjccqpjrzjq0yzeq76ney45hmjlnlpvu0nakzy2g35hqh0dujq8ujdpr2e42pf2rrs6vqpgcsqqqqqqqqqqqqqqeqqyg9qxpqysgqwftcx89k5pp28435pgxfl2vx3ksemzxccppw2j9yjn0ngr6ed7wj8ztc0d5kmt2mvzdlcgrludhz7jncd5l5l9w820hc4clpwhtqj3gq62g66n",
|
||||
"description": "Test Invoice",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 555000,
|
||||
"fees_paid": 0,
|
||||
"created_at": 0,
|
||||
"expires_at": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "error",
|
||||
"call_params": {
|
||||
"amount": 555,
|
||||
"memo": "Test Invoice",
|
||||
"label": "test-label"
|
||||
},
|
||||
"expect": {
|
||||
"error_message": "TEST ERROR test-error",
|
||||
"success": false,
|
||||
"checking_id": null,
|
||||
"payment_request": null
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"make_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "make_invoice",
|
||||
"params": {
|
||||
"amount": 555000,
|
||||
"description": "Test Invoice"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "make_invoice",
|
||||
"error": {
|
||||
"code": "TEST ERROR",
|
||||
"message": "test-error"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"pay_invoice": {
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"pay_invoice": {},
|
||||
"lookup_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "success",
|
||||
"call_params": {
|
||||
"bolt11": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"fee_limit_msat": 25000
|
||||
},
|
||||
"expect": {
|
||||
"error_message": null,
|
||||
"success": true,
|
||||
"pending": false,
|
||||
"failed": false,
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"fee_msat": 50,
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"pay_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "pay_invoice",
|
||||
"params": {
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "pay_invoice",
|
||||
"result": {
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "outgoing",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test invoice",
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 1000,
|
||||
"fees_paid": 50,
|
||||
"created_at": 0,
|
||||
"settled_at": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "failed",
|
||||
"call_params": {
|
||||
"bolt11": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"fee_limit_msat": 25000
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"pending": false,
|
||||
"failed": true,
|
||||
"checking_id": null,
|
||||
"fee_msat": null,
|
||||
"preimage": null
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"pay_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "pay_invoice",
|
||||
"params": {
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "pay_invoice",
|
||||
"error": {
|
||||
"code": "TEST ERROR",
|
||||
"message": "test-error"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"description": "error",
|
||||
"call_params": {
|
||||
"bolt11": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"fee_limit_msat": 25000
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"pending": true,
|
||||
"failed": false,
|
||||
"checking_id": null,
|
||||
"fee_msat": null,
|
||||
"preimage": null,
|
||||
"error_message": "TEST ERROR test-error"
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"pay_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "pay_invoice",
|
||||
"params": {
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "pay_invoice",
|
||||
"error": {
|
||||
"code": "TEST ERROR",
|
||||
"message": "test-error"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"get_invoice_status": {
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"lookup_invoice": {}
|
||||
},
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "paid",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"success": true,
|
||||
"failed": false,
|
||||
"pending": false
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 123,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"settled_at": 1,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "failed",
|
||||
"description1": "pending should be false in the 'expect', this is a bug",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"failed": true,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": [
|
||||
{
|
||||
"description": "nwc.py doesn't handle the 'failed' status for `get_invoice_status`"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "pending",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"failed": false,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 0,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"get_payment_status": {
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"lookup_invoice": {}
|
||||
},
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "paid",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"fee_msat": 1000,
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"success": true,
|
||||
"failed": false,
|
||||
"pending": false
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 1000,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"settled_at": 1,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "failed",
|
||||
"description1": "pending should be false in the 'expect', this is a bug",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"preimage": null,
|
||||
"success": false,
|
||||
"failed": true,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": [
|
||||
{
|
||||
"description": "nwc.py doesn't handle the 'failed' status for `get_payment_status`"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "pending",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"preimage": null,
|
||||
"success": false,
|
||||
"failed": false,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 0,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
418
tests/wallets/fixtures/json/fixtures_nwc_bad.json
Normal file
418
tests/wallets/fixtures/json/fixtures_nwc_bad.json
Normal file
@@ -0,0 +1,418 @@
|
||||
{
|
||||
"funding_sources": {
|
||||
"nwc-bad": {
|
||||
"description": "NWC service that supports only pay_invoice",
|
||||
"wallet_class": "NWCWallet",
|
||||
"settings": {
|
||||
"nwc_pairing_url": "nostr+walletconnect://be927be01ce2b3ab0fc33ffec6c6ab590381d7fc883a392d163d3966fc5840b3?relay=ws://127.0.0.1:8555&secret=d1b1d3b0f4a1fcba4c15094d34ff0569cae3c8c7af939b3473ccd564cce3bfa3"
|
||||
},
|
||||
"mock_settings": {
|
||||
"service_public_key": "be927be01ce2b3ab0fc33ffec6c6ab590381d7fc883a392d163d3966fc5840b3",
|
||||
"service_private_key": "ad6a224c9c2f2a7ac7181092348d99671a94f28974e331e0f0afe3bcdab72bed",
|
||||
"user_public_key": "bef38893a567e717110478cc5729f4bf881727f5a7d7859edad2b2b21ee81f7e",
|
||||
"user_private_key": "d1b1d3b0f4a1fcba4c15094d34ff0569cae3c8c7af939b3473ccd564cce3bfa3",
|
||||
"port": 8555,
|
||||
"supported_methods": ["pay_invoice"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"functions": {
|
||||
"status": {
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"get_balance": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "success",
|
||||
"call_params": {},
|
||||
"expect": {
|
||||
"error_message": null,
|
||||
"balance_msat": 0
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"create_invoice": {
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"make_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "success",
|
||||
"call_params": {
|
||||
"amount": 555,
|
||||
"memo": "Test Invoice",
|
||||
"label": "test-label"
|
||||
},
|
||||
"expect": {
|
||||
"error_message": "make_invoice is not supported by this NWC service.",
|
||||
"success": false
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"pay_invoice": {
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"pay_invoice": {},
|
||||
"lookup_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "success",
|
||||
"call_params": {
|
||||
"bolt11": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"fee_limit_msat": 25000
|
||||
},
|
||||
"expect": {
|
||||
"error_message": null,
|
||||
"success": true,
|
||||
"pending": false,
|
||||
"failed": false,
|
||||
"checking_id": "66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925",
|
||||
"fee_msat": 50,
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"pay_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "pay_invoice",
|
||||
"params": {
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "pay_invoice",
|
||||
"result": {
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "failed",
|
||||
"call_params": {
|
||||
"bolt11": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"fee_limit_msat": 25000
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"pending": false,
|
||||
"failed": true,
|
||||
"checking_id": null,
|
||||
"fee_msat": null,
|
||||
"preimage": null
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"pay_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "pay_invoice",
|
||||
"params": {
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "pay_invoice",
|
||||
"error": {
|
||||
"code": "TEST ERROR",
|
||||
"message": "test-error"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "error",
|
||||
"call_params": {
|
||||
"bolt11": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"fee_limit_msat": 25000
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"pending": true,
|
||||
"failed": false,
|
||||
"checking_id": null,
|
||||
"fee_msat": null,
|
||||
"preimage": null,
|
||||
"error_message": "TEST ERROR test-error"
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"pay_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "pay_invoice",
|
||||
"params": {
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "pay_invoice",
|
||||
"error": {
|
||||
"code": "TEST ERROR",
|
||||
"message": "test-error"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"get_invoice_status": {
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "paid",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"failed": false,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 123,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"settled_at": 1,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "failed",
|
||||
"description1": "pending should be false in the 'expect', this is a bug",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"failed": false,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": [
|
||||
{
|
||||
"description": "nwc.py doesn't handle the 'failed' status for `get_invoice_status`"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "pending",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"success": false,
|
||||
"failed": false,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 0,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"get_payment_status": {
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": {}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "paid",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"fee_msat": null,
|
||||
"preimage": null,
|
||||
"success": false,
|
||||
"failed": false,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"preimage": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 1000,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"settled_at": 1,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "failed",
|
||||
"description1": "pending should be false in the 'expect', this is a bug",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"preimage": null,
|
||||
"success": false,
|
||||
"failed": true,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": [
|
||||
{
|
||||
"description": "nwc.py doesn't handle the 'failed' status for `get_payment_status`"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "pending",
|
||||
"call_params": {
|
||||
"checking_id": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
},
|
||||
"expect": {
|
||||
"preimage": null,
|
||||
"success": false,
|
||||
"failed": false,
|
||||
"pending": true
|
||||
},
|
||||
"mocks": {
|
||||
"nwc-bad": {
|
||||
"lookup_invoice": [
|
||||
{
|
||||
"request_type": "json",
|
||||
"request_body": {
|
||||
"method": "lookup_invoice",
|
||||
"params": {
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96"
|
||||
}
|
||||
},
|
||||
"response_type": "json",
|
||||
"response": {
|
||||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"type": "incoming",
|
||||
"invoice": "lnbc210n1pjlgal5sp5xr3uwlfm7ltumdjyukhys0z2rw6grgm8me9k4w9vn05zt9svzzjspp5ud2jdfpaqn5c2k2vphatsjypfafyk8rcvkvwexnrhmwm94ex4jtqdqu24hxjapq23jhxapqf9h8vmmfvdjscqpjrzjqta942048v7qxh5x7pxwplhmtwfl0f25cq23jh87rhx7lgrwwvv86r90guqqnwgqqqqqqqqqqqqqqpsqyg9qxpqysgqylngsyg960lltngzy90e8n22v4j2hvjs4l4ttuy79qqefjv8q87q9ft7uhwdjakvnsgk44qyhalv6ust54x98whl3q635hkwgsyw8xgqjl7jwu",
|
||||
"description": "Test Invoice",
|
||||
"payment_hash": "e35526a43d04e985594c0dfab848814f524b1c786598ec9a63beddb2d726ac96",
|
||||
"amount": 123,
|
||||
"fees_paid": 0,
|
||||
"created_at": 0,
|
||||
"expires_at": 0,
|
||||
"metadata": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,6 +8,7 @@ class FundingSourceConfig(BaseModel):
|
||||
skip: Optional[bool]
|
||||
wallet_class: str
|
||||
settings: dict
|
||||
mock_settings: Optional[dict]
|
||||
|
||||
|
||||
class FunctionMock(BaseModel):
|
||||
|
194
tests/wallets/test_nwc_wallets.py
Normal file
194
tests/wallets/test_nwc_wallets.py
Normal file
@@ -0,0 +1,194 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import time
|
||||
from typing import Dict, cast
|
||||
|
||||
import pytest
|
||||
import secp256k1
|
||||
from Cryptodome import Random
|
||||
from Cryptodome.Cipher import AES
|
||||
from Cryptodome.Util.Padding import pad, unpad
|
||||
from websockets.server import serve as ws_serve
|
||||
|
||||
from lnbits.wallets.nwc import NWCWallet
|
||||
from tests.wallets.helpers import (
|
||||
WalletTest,
|
||||
build_test_id,
|
||||
check_assertions,
|
||||
load_funding_source,
|
||||
wallet_fixtures_from_json,
|
||||
)
|
||||
|
||||
|
||||
def encrypt_content(priv_key, dest_pub_key, content):
|
||||
p = secp256k1.PublicKey(bytes.fromhex("02" + dest_pub_key), True)
|
||||
shared = p.tweak_mul(bytes.fromhex(priv_key)).serialize()[1:]
|
||||
iv = Random.new().read(AES.block_size)
|
||||
aes = AES.new(shared, AES.MODE_CBC, iv)
|
||||
|
||||
content_bytes = content.encode("utf-8")
|
||||
content_bytes = pad(content_bytes, AES.block_size)
|
||||
|
||||
encrypted_b64 = base64.b64encode(aes.encrypt(content_bytes)).decode("ascii")
|
||||
iv_b64 = base64.b64encode(iv).decode("ascii")
|
||||
encrypted_content = encrypted_b64 + "?iv=" + iv_b64
|
||||
return encrypted_content
|
||||
|
||||
|
||||
def decrypt_content(priv_key, source_pub_key, content):
|
||||
p = secp256k1.PublicKey(bytes.fromhex("02" + source_pub_key), True)
|
||||
shared = p.tweak_mul(bytes.fromhex(priv_key)).serialize()[1:]
|
||||
(encrypted_content_b64, iv_b64) = content.split("?iv=")
|
||||
encrypted_content = base64.b64decode(encrypted_content_b64.encode("ascii"))
|
||||
iv = base64.b64decode(iv_b64.encode("ascii"))
|
||||
aes = AES.new(shared, AES.MODE_CBC, iv)
|
||||
decrypted_bytes = aes.decrypt(encrypted_content)
|
||||
decrypted_bytes = unpad(decrypted_bytes, AES.block_size)
|
||||
return decrypted_bytes.decode("utf-8")
|
||||
|
||||
|
||||
def json_dumps(data):
|
||||
if isinstance(data, Dict):
|
||||
data = {k: v for k, v in data.items() if v is not None}
|
||||
return json.dumps(data, separators=(",", ":"), ensure_ascii=False)
|
||||
|
||||
|
||||
def sign_event(pub_key, priv_key, event):
|
||||
signature_data = json_dumps(
|
||||
[
|
||||
0,
|
||||
pub_key,
|
||||
event["created_at"],
|
||||
event["kind"],
|
||||
event["tags"],
|
||||
event["content"],
|
||||
]
|
||||
)
|
||||
event_id = hashlib.sha256(signature_data.encode()).hexdigest()
|
||||
event["id"] = event_id
|
||||
event["pubkey"] = pub_key
|
||||
s = secp256k1.PrivateKey(bytes.fromhex(priv_key))
|
||||
signature = (s.schnorr_sign(bytes.fromhex(event_id), None, raw=True)).hex()
|
||||
event["sig"] = signature
|
||||
return event
|
||||
|
||||
|
||||
async def handle(wallet, mock_settings, data, websocket, path):
|
||||
async for message in websocket:
|
||||
if not wallet:
|
||||
continue
|
||||
msg = json.loads(message)
|
||||
if msg[0] == "REQ":
|
||||
sub_id = msg[1]
|
||||
sub_filter = msg[2]
|
||||
kinds = sub_filter["kinds"]
|
||||
if 13194 in kinds: # Send info event
|
||||
event = {
|
||||
"kind": 13194,
|
||||
"content": " ".join(mock_settings["supported_methods"]),
|
||||
"created_at": int(time.time()),
|
||||
"tags": [],
|
||||
}
|
||||
sign_event(
|
||||
mock_settings["service_public_key"],
|
||||
mock_settings["service_private_key"],
|
||||
event,
|
||||
)
|
||||
await websocket.send(json.dumps(["EVENT", sub_id, event]))
|
||||
elif msg[0] == "EVENT":
|
||||
event = msg[1]
|
||||
decrypted_content = decrypt_content(
|
||||
mock_settings["service_private_key"],
|
||||
mock_settings["user_public_key"],
|
||||
event["content"],
|
||||
)
|
||||
content = json.loads(decrypted_content)
|
||||
mock = None
|
||||
for m in data.mocks:
|
||||
rb = m.request_body
|
||||
if rb and rb["method"] == content["method"]:
|
||||
p1 = rb["params"]
|
||||
p2 = content["params"]
|
||||
p1 = json_dumps({k: v for k, v in p1.items() if v is not None})
|
||||
p2 = json_dumps({k: v for k, v in p2.items() if v is not None})
|
||||
if p1 == p2:
|
||||
mock = m
|
||||
break
|
||||
if mock:
|
||||
sub_id = None
|
||||
nwcwallet = cast(NWCWallet, wallet)
|
||||
for subscription in nwcwallet.conn.subscriptions.values():
|
||||
if subscription["event_id"] == event["id"]:
|
||||
sub_id = subscription["sub_id"]
|
||||
break
|
||||
if sub_id:
|
||||
response = mock.response
|
||||
encrypted_content = encrypt_content(
|
||||
mock_settings["service_private_key"],
|
||||
mock_settings["user_public_key"],
|
||||
json_dumps(response),
|
||||
)
|
||||
response_event = {
|
||||
"kind": 23195,
|
||||
"content": encrypted_content,
|
||||
"created_at": int(time.time()),
|
||||
"tags": [
|
||||
["e", event["id"]],
|
||||
["p", mock_settings["user_public_key"]],
|
||||
],
|
||||
}
|
||||
sign_event(
|
||||
mock_settings["service_public_key"],
|
||||
mock_settings["service_private_key"],
|
||||
response_event,
|
||||
)
|
||||
await websocket.send(json.dumps(["EVENT", sub_id, response_event]))
|
||||
else:
|
||||
raise Exception(
|
||||
"No mock found for "
|
||||
+ content["method"]
|
||||
+ " "
|
||||
+ json_dumps(content["params"])
|
||||
)
|
||||
|
||||
|
||||
async def run(data: WalletTest):
|
||||
if data.skip:
|
||||
pytest.skip()
|
||||
|
||||
wallet = None
|
||||
mock_settings = data.funding_source.mock_settings
|
||||
if mock_settings is None:
|
||||
return
|
||||
|
||||
async def handler(websocket, path):
|
||||
return await handle(wallet, mock_settings, data, websocket, path)
|
||||
|
||||
if mock_settings is not None:
|
||||
async with ws_serve(handler, "localhost", mock_settings["port"]) as server:
|
||||
await server.start_serving()
|
||||
wallet = load_funding_source(data.funding_source)
|
||||
await check_assertions(wallet, data)
|
||||
nwcwallet = cast(NWCWallet, wallet)
|
||||
await nwcwallet.cleanup()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"test_data",
|
||||
wallet_fixtures_from_json("tests/wallets/fixtures/json/fixtures_nwc.json"),
|
||||
ids=build_test_id,
|
||||
)
|
||||
async def test_nwc_wallet(test_data: WalletTest):
|
||||
await run(test_data)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"test_data",
|
||||
wallet_fixtures_from_json("tests/wallets/fixtures/json/fixtures_nwc_bad.json"),
|
||||
ids=build_test_id,
|
||||
)
|
||||
async def test_nwc_wallet_bad(test_data: WalletTest):
|
||||
await run(test_data)
|
Reference in New Issue
Block a user