This commit is contained in:
callebtc 2022-10-24 09:26:32 +02:00
parent 7e38d899af
commit e8e4c7f9c3
7 changed files with 125 additions and 106 deletions

View File

@ -12,7 +12,8 @@ async def m001_initial(db):
fraction BOOL, fraction BOOL,
maxsats INT, maxsats INT,
coins INT, coins INT,
keyset_id TEXT NOT NULL keyset_id TEXT NOT NULL,
issued_sat INT
); );
""" """
) )

View File

@ -8,7 +8,7 @@
<q-expansion-item group="api" dense expand-separator label="List TPoS"> <q-expansion-item group="api" dense expand-separator label="List TPoS">
<q-card> <q-card>
<q-card-section> <q-card-section>
<code><span class="text-blue">GET</span> /cashu/api/v1/cashus</code> <code><span class="text-blue">GET</span> /cashu/api/v1/mints</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5> <h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@ -18,7 +18,7 @@
<code>[&lt;cashu_object&gt;, ...]</code> <code>[&lt;cashu_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X GET {{ request.base_url }}cashu/api/v1/cashus -H "X-Api-Key: >curl -X GET {{ request.base_url }}cashu/api/v1/mints -H "X-Api-Key:
&lt;invoice_key&gt;" &lt;invoice_key&gt;"
</code> </code>
</q-card-section> </q-card-section>
@ -27,7 +27,7 @@
<q-expansion-item group="api" dense expand-separator label="Create a TPoS"> <q-expansion-item group="api" dense expand-separator label="Create a TPoS">
<q-card> <q-card>
<q-card-section> <q-card-section>
<code><span class="text-green">POST</span> /cashu/api/v1/cashus</code> <code><span class="text-green">POST</span> /cashu/api/v1/mints</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5> <h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@ -43,7 +43,7 @@
> >
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X POST {{ request.base_url }}cashu/api/v1/cashus -d '{"name": >curl -X POST {{ request.base_url }}cashu/api/v1/mints -d '{"name":
&lt;string&gt;, "currency": &lt;string&gt;}' -H "Content-type: &lt;string&gt;, "currency": &lt;string&gt;}' -H "Content-type:
application/json" -H "X-Api-Key: &lt;admin_key&gt;" application/json" -H "X-Api-Key: &lt;admin_key&gt;"
</code> </code>
@ -62,7 +62,7 @@
<q-card-section> <q-card-section>
<code <code
><span class="text-pink">DELETE</span> ><span class="text-pink">DELETE</span>
/cashu/api/v1/cashus/&lt;cashu_id&gt;</code /cashu/api/v1/mints/&lt;cashu_id&gt;</code
> >
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
@ -71,7 +71,7 @@
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X DELETE {{ request.base_url >curl -X DELETE {{ request.base_url
}}cashu/api/v1/cashus/&lt;cashu_id&gt; -H "X-Api-Key: }}cashu/api/v1/mints/&lt;cashu_id&gt; -H "X-Api-Key:
&lt;admin_key&gt;" &lt;admin_key&gt;"
</code> </code>
</q-card-section> </q-card-section>

View File

@ -271,7 +271,7 @@
LNbits.api LNbits.api
.request( .request(
'GET', 'GET',
'/cashu/api/v1/cashus?all_wallets=true', '/cashu/api/v1/mints?all_wallets=true',
this.g.user.wallets[0].inkey this.g.user.wallets[0].inkey
) )
.then(function (response) { .then(function (response) {
@ -294,7 +294,7 @@
LNbits.api LNbits.api
.request( .request(
'POST', 'POST',
'/cashu/api/v1/cashus', '/cashu/api/v1/mints',
_.findWhere(this.g.user.wallets, {id: this.formDialog.data.wallet}) _.findWhere(this.g.user.wallets, {id: this.formDialog.data.wallet})
.inkey, .inkey,
data data
@ -314,13 +314,13 @@
LNbits.utils LNbits.utils
.confirmDialog( .confirmDialog(
'Are you sure you want to delete this Mint? It will suck for users.' "Are you sure you want to delete this Mint? This mint's users will not be able to redeem their tokens!"
) )
.onOk(function () { .onOk(function () {
LNbits.api LNbits.api
.request( .request(
'DELETE', 'DELETE',
'/cashu/api/v1/cashus/' + cashuId, '/cashu/api/v1/mints/' + cashuId,
_.findWhere(self.g.user.wallets, {id: cashu.wallet}).adminkey _.findWhere(self.g.user.wallets, {id: cashu.wallet}).adminkey
) )
.then(function (response) { .then(function (response) {

View File

@ -913,7 +913,7 @@ page_container %}
try { try {
const {data} = await LNbits.api.request( const {data} = await LNbits.api.request(
'GET', 'GET',
`/cashu/api/v1/cashu/${this.mintId}/mint?amount=${this.invoiceData.amount}` `/cashu/api/v1/${this.mintId}/mint?amount=${this.invoiceData.amount}`
) )
console.log('### data', data) console.log('### data', data)
@ -940,7 +940,7 @@ page_container %}
try { try {
const {data} = await LNbits.api.request( const {data} = await LNbits.api.request(
'POST', 'POST',
`/cashu/api/v1/cashu/${this.mintId}/mint?payment_hash=${invoice.hash}`, `/cashu/api/v1/${this.mintId}/mint?payment_hash=${invoice.hash}`,
'', '',
{ {
blinded_messages: [] blinded_messages: []
@ -991,7 +991,7 @@ page_container %}
try { try {
const {data} = await LNbits.api.request( const {data} = await LNbits.api.request(
'POST', 'POST',
`/cashu/api/v1/cashu/${this.mintId}/mint?payment_hash=${hash}`, `/cashu/api/v1/${this.mintId}/mint?payment_hash=${hash}`,
'', '',
{ {
blinded_messages: blindedMessages blinded_messages: blindedMessages
@ -1086,7 +1086,7 @@ page_container %}
try { try {
const {data} = await LNbits.api.request( const {data} = await LNbits.api.request(
'POST', 'POST',
`/cashu/api/v1/cashu/${this.mintId}/split`, `/cashu/api/v1/${this.mintId}/split`,
'', '',
payload payload
) )
@ -1221,7 +1221,7 @@ page_container %}
try { try {
const {data} = await LNbits.api.request( const {data} = await LNbits.api.request(
'POST', 'POST',
`/cashu/api/v1/cashu/${this.mintId}/melt`, `/cashu/api/v1/${this.mintId}/melt`,
'', '',
payload payload
) )
@ -1257,7 +1257,7 @@ page_container %}
fetchMintKeys: async function () { fetchMintKeys: async function () {
const {data} = await LNbits.api.request( const {data} = await LNbits.api.request(
'GET', 'GET',
`/cashu/api/v1/cashu/${this.mintId}/keys` `/cashu/api/v1/${this.mintId}/keys`
) )
this.keys = data this.keys = data
localStorage.setItem('cashu.keys', JSON.stringify(data)) localStorage.setItem('cashu.keys', JSON.stringify(data))

View File

@ -47,17 +47,20 @@ from .models import Cashu
# --------- extension imports # --------- extension imports
LIGHTNING = False LIGHTNING = True
######################################## ########################################
############### LNBITS MINTS ########### ############### LNBITS MINTS ###########
######################################## ########################################
# todo: use /mints
@cashu_ext.get("/api/v1/cashus", status_code=HTTPStatus.OK) @cashu_ext.get("/api/v1/mints", status_code=HTTPStatus.OK)
async def api_cashus( async def api_cashus(
all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type) all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)
): ):
"""
Get all mints of this wallet.
"""
wallet_ids = [wallet.wallet.id] wallet_ids = [wallet.wallet.id]
if all_wallets: if all_wallets:
wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids
@ -65,8 +68,11 @@ async def api_cashus(
return [cashu.dict() for cashu in await get_cashus(wallet_ids)] return [cashu.dict() for cashu in await get_cashus(wallet_ids)]
@cashu_ext.post("/api/v1/cashus", status_code=HTTPStatus.CREATED) @cashu_ext.post("/api/v1/mints", status_code=HTTPStatus.CREATED)
async def api_cashu_create(data: Cashu, wallet: WalletTypeInfo = Depends(get_key_type)): async def api_cashu_create(data: Cashu, wallet: WalletTypeInfo = Depends(get_key_type)):
"""
Create a new mint for this wallet.
"""
cashu_id = urlsafe_short_hash() cashu_id = urlsafe_short_hash()
# generate a new keyset in cashu # generate a new keyset in cashu
keyset = await ledger.load_keyset(cashu_id) keyset = await ledger.load_keyset(cashu_id)
@ -78,12 +84,35 @@ async def api_cashu_create(data: Cashu, wallet: WalletTypeInfo = Depends(get_key
return cashu.dict() return cashu.dict()
@cashu_ext.delete("/api/v1/mints/{cashu_id}")
async def api_cashu_delete(
cashu_id: str, wallet: WalletTypeInfo = Depends(require_admin_key)
):
"""
Delete an existing cashu mint.
"""
cashu = await get_cashu(cashu_id)
if not cashu:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Cashu mint does not exist."
)
if cashu.wallet != wallet.wallet.id:
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, detail="Not your Cashu mint."
)
await delete_cashu(cashu_id)
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
####################################### #######################################
########### CASHU ENDPOINTS ########### ########### CASHU ENDPOINTS ###########
####################################### #######################################
@cashu_ext.get("/api/v1/cashu/{cashu_id}/keys", status_code=HTTPStatus.OK) @cashu_ext.get("/api/v1/{cashu_id}/keys", status_code=HTTPStatus.OK)
async def keys(cashu_id: str = Query(None)) -> dict[int, str]: async def keys(cashu_id: str = Query(None)) -> dict[int, str]:
"""Get the public keys of the mint""" """Get the public keys of the mint"""
cashu: Union[Cashu, None] = await get_cashu(cashu_id) cashu: Union[Cashu, None] = await get_cashu(cashu_id)
@ -96,7 +125,20 @@ async def keys(cashu_id: str = Query(None)) -> dict[int, str]:
return ledger.get_keyset(keyset_id=cashu.keyset_id) return ledger.get_keyset(keyset_id=cashu.keyset_id)
@cashu_ext.get("/api/v1/cashu/{cashu_id}/mint") @cashu_ext.get("/api/v1/{cashu_id}/keysets", status_code=HTTPStatus.OK)
async def keysets(cashu_id: str = Query(None)) -> dict[str, list[str]]:
"""Get the public keys of the mint"""
cashu: Union[Cashu, None] = await get_cashu(cashu_id)
if not cashu:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Mint does not exist."
)
return {"keysets": [cashu.keyset_id]}
@cashu_ext.get("/api/v1/{cashu_id}/mint")
async def request_mint(cashu_id: str = Query(None), amount: int = 0) -> GetMintResponse: async def request_mint(cashu_id: str = Query(None), amount: int = 0) -> GetMintResponse:
""" """
Request minting of new tokens. The mint responds with a Lightning invoice. Request minting of new tokens. The mint responds with a Lightning invoice.
@ -134,7 +176,7 @@ async def request_mint(cashu_id: str = Query(None), amount: int = 0) -> GetMintR
return resp return resp
@cashu_ext.post("/api/v1/cashu/{cashu_id}/mint") @cashu_ext.post("/api/v1/{cashu_id}/mint")
async def mint_coins( async def mint_coins(
data: MintRequest, data: MintRequest,
cashu_id: str = Query(None), cashu_id: str = Query(None),
@ -157,7 +199,7 @@ async def mint_coins(
if invoice is None: if invoice is None:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, status_code=HTTPStatus.NOT_FOUND,
detail="Mint does not have this invoice.", detail="Mint does not know this invoice.",
) )
if invoice.issued == True: if invoice.issued == True:
raise HTTPException( raise HTTPException(
@ -173,27 +215,31 @@ async def mint_coins(
) )
status: PaymentStatus = await check_transaction_status(cashu.wallet, payment_hash) status: PaymentStatus = await check_transaction_status(cashu.wallet, payment_hash)
# todo: revert to: status.paid != True:
if status.paid != True: if status.paid != True:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.PAYMENT_REQUIRED, detail="Invoice not paid." status_code=HTTPStatus.PAYMENT_REQUIRED, detail="Invoice not paid."
) )
try: try:
await ledger.crud.update_lightning_invoice(
db=ledger.db, hash=payment_hash, issued=True
)
keyset = ledger.keysets.keysets[cashu.keyset_id] keyset = ledger.keysets.keysets[cashu.keyset_id]
promises = await ledger._generate_promises( promises = await ledger._generate_promises(
B_s=data.blinded_messages, keyset=keyset B_s=data.blinded_messages, keyset=keyset
) )
assert len(promises), HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="No promises returned."
)
await ledger.crud.update_lightning_invoice(
db=ledger.db, hash=payment_hash, issued=True
)
return promises return promises
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e))
@cashu_ext.post("/api/v1/cashu/{cashu_id}/melt") @cashu_ext.post("/api/v1/{cashu_id}/melt")
async def melt_coins( async def melt_coins(
payload: MeltRequest, cashu_id: str = Query(None) payload: MeltRequest, cashu_id: str = Query(None)
) -> GetMeltResponse: ) -> GetMeltResponse:
@ -211,7 +257,7 @@ async def melt_coins(
# TOKENS # TOKENS
assert all([p.id == cashu.keyset_id for p in proofs]), HTTPException( assert all([p.id == cashu.keyset_id for p in proofs]), HTTPException(
status_code=HTTPStatus.BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
detail="Proofs include tokens from other mint.", detail="Proofs include tokens from another mint.",
) )
assert all([ledger._verify_proof(p) for p in proofs]), HTTPException( assert all([ledger._verify_proof(p) for p in proofs]), HTTPException(
@ -248,19 +294,33 @@ async def melt_coins(
return GetMeltResponse(paid=status.paid, preimage=status.preimage) return GetMeltResponse(paid=status.paid, preimage=status.preimage)
@cashu_ext.post("/api/v1/check") @cashu_ext.post("/api/v1/{cashu_id}/check")
async def check_spendable(payload: CheckRequest) -> Dict[int, bool]: async def check_spendable(
payload: CheckRequest, cashu_id: str = Query(None)
) -> Dict[int, bool]:
"""Check whether a secret has been spent already or not.""" """Check whether a secret has been spent already or not."""
cashu: Union[None, Cashu] = await get_cashu(cashu_id)
if cashu is None:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Mint does not exist."
)
return await ledger.check_spendable(payload.proofs) return await ledger.check_spendable(payload.proofs)
@cashu_ext.post("/api/v1/checkfees") @cashu_ext.post("/api/v1/{cashu_id}/checkfees")
async def check_fees(payload: CheckFeesRequest) -> CheckFeesResponse: async def check_fees(
payload: CheckFeesRequest, cashu_id: str = Query(None)
) -> CheckFeesResponse:
""" """
Responds with the fees necessary to pay a Lightning invoice. Responds with the fees necessary to pay a Lightning invoice.
Used by wallets for figuring out the fees they need to supply. Used by wallets for figuring out the fees they need to supply.
This is can be useful for checking whether an invoice is internal (Cashu-to-Cashu). This is can be useful for checking whether an invoice is internal (Cashu-to-Cashu).
""" """
cashu: Union[None, Cashu] = await get_cashu(cashu_id)
if cashu is None:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Mint does not exist."
)
invoice_obj = bolt11.decode(payload.pr) invoice_obj = bolt11.decode(payload.pr)
internal_checking_id = await check_internal(invoice_obj.payment_hash) internal_checking_id = await check_internal(invoice_obj.payment_hash)
@ -271,7 +331,7 @@ async def check_fees(payload: CheckFeesRequest) -> CheckFeesResponse:
return CheckFeesResponse(fee=fees_msat / 1000) return CheckFeesResponse(fee=fees_msat / 1000)
@cashu_ext.post("/api/v1/cashu/{cashu_id}/split") @cashu_ext.post("/api/v1/{cashu_id}/split")
async def split( async def split(
payload: SplitRequest, cashu_id: str = Query(None) payload: SplitRequest, cashu_id: str = Query(None)
) -> PostSplitResponse: ) -> PostSplitResponse:
@ -291,7 +351,8 @@ async def split(
assert outputs, Exception("no outputs provided.") assert outputs, Exception("no outputs provided.")
split_return = None split_return = None
try: try:
split_return = await ledger.split(proofs, amount, outputs, cashu.keyset_id) keyset = ledger.keysets.keysets[cashu.keyset_id]
split_return = await ledger.split(proofs, amount, outputs, keyset)
except Exception as exc: except Exception as exc:
HTTPException( HTTPException(
status_code=HTTPStatus.BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
@ -318,24 +379,6 @@ async def split(
# return cashu.dict() # return cashu.dict()
# @cashu_ext.delete("/api/v1s/{cashu_id}")
# async def api_cashu_delete(
# cashu_id: str, wallet: WalletTypeInfo = Depends(require_admin_key)
# ):
# cashu = await get_cashu(cashu_id)
# if not cashu:
# raise HTTPException(
# status_code=HTTPStatus.NOT_FOUND, detail="Cashu does not exist."
# )
# if cashu.wallet != wallet.wallet.id:
# raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your Cashu.")
# await delete_cashu(cashu_id)
# raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
# ######################################## # ########################################
# #################????################### # #################????###################
# ######################################## # ########################################

75
poetry.lock generated
View File

@ -124,55 +124,33 @@ uvloop = ["uvloop (>=0.15.2)"]
[[package]] [[package]]
name = "cashu" name = "cashu"
version = "0.4.2" version = "0.4.2"
description = "Ecash wallet and mint with Bitcoin Lightning support" description = "Ecash wallet and mint."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = "^3.7"
develop = false
[package.dependencies] [package.dependencies]
anyio = {version = "3.6.2", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} bech32 = "^1.2.0"
attrs = {version = "22.1.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} bitstring = "^3.1.9"
bech32 = {version = "1.2.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} click = "8.0.4"
bitstring = {version = "3.1.9", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} ecdsa = "^0.18.0"
certifi = {version = "2022.9.24", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} environs = "^9.5.0"
cffi = {version = "1.15.1", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} fastapi = "^0.83.0"
charset-normalizer = {version = "2.0.12", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} h11 = "0.12.0"
click = {version = "8.0.4", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} loguru = "^0.6.0"
colorama = {version = "0.4.5", markers = "python_version >= \"3.7\" and python_version < \"4.0\" and platform_system == \"Windows\" or python_version >= \"3.7\" and python_version < \"4.0\" and sys_platform == \"win32\""} pydantic = "^1.10.2"
ecdsa = {version = "0.18.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} pytest-asyncio = "0.19.0"
environs = {version = "9.5.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} python-bitcoinlib = "^0.11.2"
fastapi = {version = "0.83.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} requests = "2.27.1"
h11 = {version = "0.12.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} secp256k1 = "^0.14.0"
idna = {version = "3.4", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} SQLAlchemy = "1.3.24"
importlib-metadata = {version = "5.0.0", markers = "python_version >= \"3.7\" and python_version < \"3.8\""} sqlalchemy-aio = "^0.17.0"
iniconfig = {version = "1.1.1", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} uvicorn = "^0.18.3"
loguru = {version = "0.6.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
marshmallow = {version = "3.18.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} [package.source]
outcome = {version = "1.2.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} type = "directory"
packaging = {version = "21.3", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} url = "../cashu"
pluggy = {version = "1.0.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
py = {version = "1.11.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
pycparser = {version = "2.21", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
pydantic = {version = "1.10.2", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
pyparsing = {version = "3.0.9", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
pytest = {version = "7.1.3", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
pytest-asyncio = {version = "0.19.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
python-bitcoinlib = {version = "0.11.2", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
python-dotenv = {version = "0.21.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
represent = {version = "1.6.0.post0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
requests = {version = "2.27.1", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
secp256k1 = {version = "0.14.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
six = {version = "1.16.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
sniffio = {version = "1.3.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
sqlalchemy = {version = "1.3.24", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
sqlalchemy-aio = {version = "0.17.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
starlette = {version = "0.19.1", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
tomli = {version = "2.0.1", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
typing-extensions = {version = "4.4.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
urllib3 = {version = "1.26.12", markers = "python_version >= \"3.7\" and python_version < \"4\""}
uvicorn = {version = "0.18.3", markers = "python_version >= \"3.7\" and python_version < \"4.0\""}
win32-setctime = {version = "1.1.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\" and sys_platform == \"win32\""}
zipp = {version = "3.9.0", markers = "python_version >= \"3.7\" and python_version < \"3.8\""}
[[package]] [[package]]
name = "Cerberus" name = "Cerberus"
@ -1143,7 +1121,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.10 | ^3.9 | ^3.8 | ^3.7" python-versions = "^3.10 | ^3.9 | ^3.8 | ^3.7"
content-hash = "7de5e4d432bff49de536b1c90082a6a0821533b3d0fa9d92c22ccaa758d1a65f" content-hash = "ded9ab80b3bec75bf904c3f598afbdff5f1577aaedbec25045c3b42c332f8ccc"
[metadata.files] [metadata.files]
aiofiles = [ aiofiles = [
@ -1206,10 +1184,7 @@ black = [
{file = "black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"}, {file = "black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"},
{file = "black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"}, {file = "black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"},
] ]
cashu = [ cashu = []
{file = "cashu-0.4.2-py3-none-any.whl", hash = "sha256:6d24f5e921c33dae1b6823f5e34feab0d6d5662b56a67c29095d48241163a887"},
{file = "cashu-0.4.2.tar.gz", hash = "sha256:97564481501cbe163e6be4d3cdd0d52d2841e15b830a0185c3c329657e4b8c36"},
]
Cerberus = [ Cerberus = [
{file = "Cerberus-1.3.4.tar.gz", hash = "sha256:d1b21b3954b2498d9a79edf16b3170a3ac1021df88d197dc2ce5928ba519237c"}, {file = "Cerberus-1.3.4.tar.gz", hash = "sha256:d1b21b3954b2498d9a79edf16b3170a3ac1021df88d197dc2ce5928ba519237c"},
] ]

View File

@ -64,7 +64,7 @@ protobuf = "^4.21.6"
Cerberus = "^1.3.4" Cerberus = "^1.3.4"
async-timeout = "^4.0.2" async-timeout = "^4.0.2"
pyln-client = "0.11.1" pyln-client = "0.11.1"
cashu = "0.4.2" cashu = {path = "../cashu"}
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]