Skip to content
Next
Projects
Groups
Snippets
Help
Sign in / Register
Toggle navigation
Minds Backend - Engine
Project overview
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
298
Merge Requests
40
CI / CD
Security & Compliance
Packages
Wiki
Snippets
Members
Collapse sidebar
Close sidebar
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
Minds Backend - Engine
Commits
6fbcf63c
Commit
6fbcf63c
authored
50 minutes ago
by
Emiliano Balbuena
Browse files
Options
Download
(refactor): Tweak flow and add all Request props to DB
parent
6b846ec1
goal/withdrawals-approval
1 merge request
!393
WIP: (feat): Withdrawal status support
Pipeline
#95178026
failed with stages
in 2 minutes and 45 seconds
Changes
8
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
234 additions
and
35 deletions
+234
-35
Controllers/api/v2/admin/rewards/withdrawals.php
View file @
6fbcf63c
<?php
namespace
Minds\Controllers\api\v2\admin\rewards
;
use
Exception
;
use
Minds\Api\Exportable
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Rewards\Withdraw\Manager
;
use
Minds\Core\Rewards\Withdraw\Repository
;
use
Minds\Core\Rewards\Withdraw\Request
;
use
Minds\Entities\User
;
use
Minds\Interfaces
;
use
Minds\Api\Factory
;
...
...
@@ -13,7 +17,7 @@ class withdrawals implements Interfaces\Api, Interfaces\ApiAdminPam
* Equivalent to HTTP GET method
* @param array $pages
* @return mixed|null
* @throws
\
Exception
* @throws Exception
*/
public
function
get
(
$pages
)
{
...
...
@@ -59,6 +63,37 @@ class withdrawals implements Interfaces\Api, Interfaces\ApiAdminPam
*/
public
function
put
(
$pages
)
{
/** @var Manager $manager */
$manager
=
Di
::
_
()
->
get
(
'Rewards\Withdraw\Manager'
);
$request
=
$manager
->
get
(
(
new
Request
())
->
setUserGuid
((
string
)
$pages
[
0
]
??
null
)
->
setTimestamp
((
int
)
$pages
[
1
]
??
null
)
->
setTx
((
string
)
$pages
[
2
]
??
null
)
);
if
(
!
$request
)
{
return
Factory
::
response
([
'status'
=>
'error'
,
'message'
=>
$errorMessage
??
'Missing request'
,
]);
}
try
{
$success
=
$manager
->
approve
(
$request
);
}
catch
(
Exception
$exception
)
{
$success
=
false
;
$errorMessage
=
$exception
->
getMessage
();
}
if
(
!
$success
)
{
return
Factory
::
response
([
'status'
=>
'error'
,
'message'
=>
$errorMessage
??
'Cannot approve request'
,
]);
}
return
Factory
::
response
([]);
}
...
...
@@ -69,6 +104,37 @@ class withdrawals implements Interfaces\Api, Interfaces\ApiAdminPam
*/
public
function
delete
(
$pages
)
{
/** @var Manager $manager */
$manager
=
Di
::
_
()
->
get
(
'Rewards\Withdraw\Manager'
);
$request
=
$manager
->
get
(
(
new
Request
())
->
setUserGuid
((
string
)
$pages
[
0
]
??
null
)
->
setTimestamp
((
int
)
$pages
[
1
]
??
null
)
->
setTx
((
string
)
$pages
[
2
]
??
null
)
);
if
(
!
$request
)
{
return
Factory
::
response
([
'status'
=>
'error'
,
'message'
=>
$errorMessage
??
'Missing request'
,
]);
}
try
{
$success
=
$manager
->
reject
(
$request
);
}
catch
(
Exception
$exception
)
{
$success
=
false
;
$errorMessage
=
$exception
->
getMessage
();
}
if
(
!
$success
)
{
return
Factory
::
response
([
'status'
=>
'error'
,
'message'
=>
$errorMessage
??
'Cannot reject request'
,
]);
}
return
Factory
::
response
([]);
}
}
This diff is collapsed.
Controllers/api/v2/blockchain/transactions.php
View file @
6fbcf63c
...
...
@@ -123,10 +123,11 @@ class transactions implements Interfaces\Api
break
;
case
"withdraw"
:
$request
=
new
Withdraw\Request
();
$request
->
setTx
(
$_POST
[
'tx'
])
$request
->
setUserGuid
(
Session
::
getLoggedInUser
()
->
guid
)
->
setAddress
(
$_POST
[
'address'
])
->
setTimestamp
(
time
())
->
setTx
(
$_POST
[
'tx'
])
->
setAddress
(
$_POST
[
'address'
])
->
setGas
(
$_POST
[
'gas'
])
->
setAmount
((
string
)
BigNumber
::
_
(
$_POST
[
'amount'
]));
...
...
This diff is collapsed.
Core/Blockchain/Events/WithdrawEvent.php
View file @
6fbcf63c
...
...
@@ -92,21 +92,36 @@ class WithdrawEvent implements BlockchainEventInterface
$gas
=
(
string
)
BigNumber
::
fromHex
(
$gas
);
$amount
=
(
string
)
BigNumber
::
fromHex
(
$amount
);
//double check the details of this transaction match with what the user actually requested
$request
=
new
Request
();
$request
->
setTx
(
$tx
)
->
setAddress
(
$address
)
->
setUserGuid
(
$user_guid
)
->
setGas
(
$gas
)
->
setTimestamp
(
$transaction
->
getTimestamp
())
->
setAmount
(
$amount
);
try
{
$request
=
$this
->
manager
->
get
(
(
new
Request
())
->
setUserGuid
(
$user_guid
)
->
setTimestamp
(
$transaction
->
getTimestamp
())
->
setTx
(
$tx
)
);
if
(
!
$request
)
{
throw
new
\Exception
(
'Unknown withdrawal'
);
}
if
((
string
)
$address
!==
(
string
)
$request
->
getAddress
())
{
throw
new
\Exception
(
'Wrong address value'
);
}
elseif
((
string
)
$gas
!==
(
string
)
$request
->
getGas
())
{
throw
new
\Exception
(
'Wrong gas value'
);
}
elseif
((
string
)
$amount
!==
(
string
)
$request
->
getAmount
())
{
throw
new
\Exception
(
'Wrong amount value'
);
}
$this
->
manager
->
confirm
(
$request
,
$transaction
);
}
catch
(
Exception
$e
)
{
error_log
(
print_r
(
$e
,
true
));
$this
->
manager
->
fail
(
(
new
Request
())
->
setUserGuid
(
$user_guid
)
->
setTimestamp
(
$transaction
->
getTimestamp
())
->
setTx
(
$tx
)
);
error_log
(
$e
);
}
}
...
...
@@ -114,7 +129,6 @@ class WithdrawEvent implements BlockchainEventInterface
{
if
(
$transaction
->
getContract
()
!==
'withdraw'
)
{
throw
new
Exception
(
"Failed but not a withdrawal"
);
return
;
}
$transaction
->
setFailed
(
true
);
...
...
This diff is collapsed.
Core/Provisioner/Provisioners/cassandra-provision.cql
View file @
6fbcf63c
...
...
@@ -1525,7 +1525,7 @@ CREATE TABLE minds.notification_batches (
primary key (user_guid, batch_id)
);
ALTER TABLE minds.withdrawals ADD
status text
;
ALTER TABLE minds.withdrawals ADD
(status text, address text, gas varint)
;
CREATE MATERIALIZED VIEW minds.withdrawals_by_status AS
SELECT *
...
...
This diff is collapsed.
Core/Rewards/Withdraw/Delegates/NotificationsDelegate.php
View file @
6fbcf63c
...
...
@@ -59,6 +59,22 @@ class NotificationsDelegate
]);
}
/**
* @param Request $request
*/
public
function
onFail
(
Request
$request
)
:
void
{
$message
=
'Your token withdrawal request transaction failed. Please contact an administrator.'
;
$this
->
dispatcher
->
trigger
(
'notification'
,
'all'
,
[
'to'
=>
[
$request
->
getUserGuid
()
],
'from'
=>
100000000000000519
,
'notification_view'
=>
'custom_message'
,
'params'
=>
[
'message'
=>
$message
],
'message'
=>
$message
,
]);
}
/**
* @param Request $request
* @throws Exception
...
...
This diff is collapsed.
Core/Rewards/Withdraw/Manager.php
View file @
6fbcf63c
...
...
@@ -83,10 +83,35 @@ class Manager
/**
* @param Request $request
* @return
void
* @return
Request|null
* @throws Exception
*/
public
function
request
(
$request
)
public
function
get
(
Request
$request
)
:
?
Request
{
if
(
!
$request
->
getUserGuid
()
||
!
$request
->
getTimestamp
()
||
!
$request
->
getTx
()
)
{
throw
new
Exception
(
'Missing request keys'
);
}
$requests
=
$this
->
repository
->
getList
([
'user_guid'
=>
$request
->
getUserGuid
(),
'timestamp'
=>
$request
->
getTimestamp
(),
'tx'
=>
$request
->
getTx
(),
'limit'
=>
1
,
]);
return
$requests
[
'withdrawals'
][
0
]
??
null
;
}
/**
* @param Request $request
* @return bool
* @throws Exception
*/
public
function
request
(
$request
)
:
bool
{
if
(
!
$this
->
check
(
$request
->
getUserGuid
()))
{
throw
new
Exception
(
'A withdrawal has already been requested in the last 24 hours'
);
...
...
@@ -139,21 +164,29 @@ class Manager
// Notify
$this
->
notificationsDelegate
->
onRequest
(
$request
);
//
return
true
;
}
/**
* @param Request $request
* @param Transaction $transaction - the transaction we store
* @return
void
* @return
bool
* @throws Exception
*/
public
function
confirm
(
Request
$request
,
$transaction
)
public
function
confirm
(
Request
$request
,
Transaction
$transaction
)
:
bool
{
if
(
$request
->
getUserGuid
()
!=
$transaction
->
getUserGuid
())
{
if
(
$request
->
getStatus
()
!==
'pending'
)
{
throw
new
Exception
(
'Request is not pending'
);
}
if
((
string
)
$request
->
getUserGuid
()
!==
(
string
)
$transaction
->
getUserGuid
())
{
throw
new
Exception
(
'The user who requested this operation does not match the transaction'
);
}
if
(
strtolower
(
$request
->
getAddress
())
!=
strtolower
(
$transaction
->
getData
()[
'address'
]))
{
if
(
strtolower
(
$request
->
getAddress
())
!=
=
strtolower
(
$transaction
->
getData
()[
'address'
]))
{
throw
new
Exception
(
'The address does not match the transaction'
);
}
...
...
@@ -182,7 +215,7 @@ class Manager
->
create
();
}
catch
(
LockFailedException
$e
)
{
$this
->
txManager
->
add
(
$transaction
);
return
;
return
false
;
}
// Set request status
...
...
@@ -197,14 +230,55 @@ class Manager
// Notify
$this
->
notificationsDelegate
->
onConfirm
(
$request
);
//
return
true
;
}
/**
* @param Request $request
* @return bool
* @throws Exception
*/
public
function
approve
(
Request
$request
)
public
function
fail
(
Request
$request
)
:
bool
{
if
(
$request
->
getStatus
()
!==
'pending'
)
{
throw
new
Exception
(
'Request is not pending'
);
}
$user
=
new
User
;
$user
->
guid
=
(
string
)
$request
->
getUserGuid
();
// Set request status
$request
->
setStatus
(
'failed'
);
// Update
$this
->
repository
->
add
(
$request
);
// Notify
$this
->
notificationsDelegate
->
onFail
(
$request
);
//
return
true
;
}
/**
* @param Request $request
* @return bool
* @throws Exception
*/
public
function
approve
(
Request
$request
)
:
bool
{
if
(
$request
->
getStatus
()
!==
'pending_approval'
)
{
throw
new
Exception
(
'Request is not pending approval'
);
}
// Send blockchain transaction
$txHash
=
$this
->
eth
->
sendRawTransaction
(
$this
->
config
->
get
(
'blockchain'
)[
'contracts'
][
'withdraw'
][
'wallet_pkey'
],
[
...
...
@@ -234,14 +308,23 @@ class Manager
// Notify
$this
->
notificationsDelegate
->
onApprove
(
$request
);
//
return
true
;
}
/**
* @param Request $request
* @return bool
* @throws Exception
*/
public
function
reject
(
Request
$request
)
public
function
reject
(
Request
$request
)
:
bool
{
if
(
$request
->
getStatus
()
!==
'pending_approval'
)
{
throw
new
Exception
(
'Request is not pending approval'
);
}
$user
=
new
User
;
$user
->
guid
=
(
string
)
$request
->
getUserGuid
();
...
...
@@ -254,7 +337,7 @@ class Manager
->
setAmount
((
string
)
BigNumber
::
_
(
$request
->
getAmount
()))
->
create
();
}
catch
(
LockFailedException
$e
)
{
throw
new
\
Exception
(
'Cannot refund rejected withdrawal tokens'
);
throw
new
Exception
(
'Cannot refund rejected withdrawal tokens'
);
}
// Set request status
...
...
@@ -269,5 +352,9 @@ class Manager
// Notify
$this
->
notificationsDelegate
->
onReject
(
$request
);
//
return
true
;
}
}
This diff is collapsed.
Core/Rewards/Withdraw/Repository.php
View file @
6fbcf63c
...
...
@@ -57,6 +57,16 @@ class Repository
$values
[]
=
new
Varint
(
$opts
[
'user_guid'
]);
}
if
(
$opts
[
'timestamp'
])
{
$where
[]
=
'timestamp = ?'
;
$values
[]
=
new
Timestamp
(
$opts
[
'timestamp'
]);
}
if
(
$opts
[
'tx'
])
{
$where
[]
=
'tx = ?'
;
$values
[]
=
(
string
)
$opts
[
'tx'
];
}
if
(
$opts
[
'from'
])
{
$where
[]
=
'timestamp >= ?'
;
$values
[]
=
new
Timestamp
(
$opts
[
'from'
]);
...
...
@@ -92,11 +102,14 @@ class Repository
$request
->
setUserGuid
((
string
)
$row
[
'user_guid'
]
->
value
())
->
setTimestamp
(
$row
[
'timestamp'
]
->
time
())
->
setAmount
((
string
)
BigNumber
::
_
(
$row
[
'amount'
]))
->
setTx
(
$row
[
'tx'
])
->
setStatus
(
$row
[
'status'
]
?:
''
)
->
setAddress
(
$row
[
'address'
]
?:
''
)
->
setAmount
((
string
)
BigNumber
::
_
(
$row
[
'amount'
]))
->
setCompleted
((
bool
)
$row
[
'completed'
])
->
setCompletedTx
(
$row
[
'completed_tx'
]);
->
setCompletedTx
(
$row
[
'completed_tx'
]
?:
null
)
->
setGas
((
string
)
BigNumber
::
_
(
$row
[
'gas'
]))
->
setStatus
(
$row
[
'status'
]
?:
''
)
;
$requests
[]
=
$request
;
}
...
...
@@ -117,15 +130,17 @@ class Repository
*/
public
function
add
(
Request
$request
)
{
$cql
=
"INSERT INTO withdrawals (user_guid, timestamp,
amount, tx, status, completed, completed_tx) VALUES (
?, ?, ?, ?, ?, ?, ?)"
;
$cql
=
"INSERT INTO withdrawals (user_guid, timestamp,
tx, address, amount, completed, completed_tx, gas, status) VALUES (?, ?,
?, ?, ?, ?, ?, ?, ?)"
;
$values
=
[
new
Varint
(
$request
->
getUserGuid
()),
new
Timestamp
(
$request
->
getTimestamp
()),
new
Varint
(
$request
->
getAmount
()),
$request
->
getTx
(),
$request
->
getStatus
(),
(
string
)
$request
->
getAddress
(),
new
Varint
(
$request
->
getAmount
()),
(
bool
)
$request
->
isCompleted
(),
$request
->
getCompletedTx
(),
((
string
)
$request
->
getCompletedTx
())
?:
null
,
new
Varint
(
$request
->
getGas
()),
(
string
)
$request
->
getStatus
(),
];
$prepared
=
new
Custom
();
...
...
This diff is collapsed.
Core/Rewards/Withdraw/Request.php
View file @
6fbcf63c
...
...
@@ -20,7 +20,7 @@ use Minds\Traits\MagicAttributes;
* @method Request setAmount(string $amount)
* @method string getStatus()
* @method Request setStatus(string $status)
* @method bool
get
Completed()
* @method bool
is
Completed()
* @method Request setCompleted(bool $completed)
* @method int getTimestamp()
* @method Request setTimestamp(int $timestamp)
...
...
This diff is collapsed.
Please
register
or
sign in
to comment