From ea92ef78ef5fe8c8572208bc89a71a46d3cdb0a1 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Thu, 16 May 2024 08:18:34 -0600 Subject: [PATCH] Enable token storage in asset wallet notebooks Expose and use the necessary interfaces for tokens to be included in wallet notebooks. The big benefit of this is that all "ownership" functions can now be handled through the same interface whether they are fungible assets (like marbles) or non-fungible assets (like tokens). Needed to support the "get_balance" method in the token contract (we already support many of the other issuer methods through tokens). Added better support for the balance and transfer in the plugins. And... most notably, added an "issuer" reference in the context file. Context references turn out to be rather useful. This creates a reference to the specific token object in the collections file. So now there is a canonical reference point for accessing issuer functions. Signed-off-by: Mic Bowman --- exchange-contract/contracts/token_object.cpp | 1 + .../docs/notebooks/templates/token.py | 5 +++- .../exchange/contracts/token_object.cpp | 24 +++++++++++++++++++ exchange-contract/exchange/token_object.h | 1 + .../pdo/exchange/plugins/token_object.py | 10 ++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/exchange-contract/contracts/token_object.cpp b/exchange-contract/contracts/token_object.cpp index 5704201..bd7c195 100644 --- a/exchange-contract/contracts/token_object.cpp +++ b/exchange-contract/contracts/token_object.cpp @@ -93,6 +93,7 @@ contract_method_reference_t contract_method_dispatch_table[] = { CONTRACT_METHOD(echo), // object transfer, escrow & claim methods + CONTRACT_METHOD2(get_balance,ww::exchange::token_object::get_balance), CONTRACT_METHOD2(transfer,ww::exchange::token_object::transfer), CONTRACT_METHOD2(escrow,ww::exchange::token_object::escrow), CONTRACT_METHOD2(escrow_attestation,ww::exchange::token_object::escrow_attestation), diff --git a/exchange-contract/docs/notebooks/templates/token.py b/exchange-contract/docs/notebooks/templates/token.py index b066ed1..17755ea 100644 --- a/exchange-contract/docs/notebooks/templates/token.py +++ b/exchange-contract/docs/notebooks/templates/token.py @@ -135,8 +135,11 @@ def token_transfer(new_owner) : # free to change the file name as well. The default uses the asset name. # %% +# this adds a reference key to "issuer" which makes the wallets work with tokens +context.set('issuer', '@{.token_object.' + token_name + '}') + contract_identifier = '{}_{}'.format(token_class, instance_identifier) -contexts = ['asset_type', 'vetting', 'guardian', 'token_issuer', 'token_object'] +contexts = ['asset_type', 'issuer', 'vetting', 'guardian', 'token_issuer', 'token_object'] contract_files = { 'token' : token_context.get('save_file'), } diff --git a/exchange-contract/exchange/contracts/token_object.cpp b/exchange-contract/exchange/contracts/token_object.cpp index f9ed398..0ff2425 100644 --- a/exchange-contract/exchange/contracts/token_object.cpp +++ b/exchange-contract/exchange/contracts/token_object.cpp @@ -139,6 +139,30 @@ bool ww::exchange::token_object::initialize( return rsp.success(true); } +// ----------------------------------------------------------------- +// METHOD: get_balance +// +// JSON PARAMETERS: +// none +// +// RETURNS: +// current number of assets assigned to the requestor +// ----------------------------------------------------------------- +bool ww::exchange::token_object::get_balance(const Message& msg, const Environment& env, Response& rsp) +{ + ASSERT_INITIALIZED(rsp); + + int count = 0; + std::string owner; + + ASSERT_SUCCESS(rsp, ww::contract::base::get_owner(owner), "failed to retrieve owner"); + if (env.originator_id_ == owner) + count = 1; + + ww::value::Number balance(count); + return rsp.value(balance, false); +} + // ----------------------------------------------------------------- // transfer // ----------------------------------------------------------------- diff --git a/exchange-contract/exchange/token_object.h b/exchange-contract/exchange/token_object.h index ec5bf36..163e186 100644 --- a/exchange-contract/exchange/token_object.h +++ b/exchange-contract/exchange/token_object.h @@ -62,6 +62,7 @@ namespace token_object bool initialize(const Message& msg, const Environment& env, Response& rsp); // the interface for these methods is copied from issuer contract + bool get_balance(const Message& msg, const Environment& env, Response& rsp); bool transfer(const Message& msg, const Environment& env, Response& rsp); bool escrow(const Message& msg, const Environment& env, Response& rsp); bool escrow_attestation(const Message& msg, const Environment& env, Response& rsp); diff --git a/exchange-contract/pdo/exchange/plugins/token_object.py b/exchange-contract/pdo/exchange/plugins/token_object.py index dcb9e2d..35ba2e6 100644 --- a/exchange-contract/pdo/exchange/plugins/token_object.py +++ b/exchange-contract/pdo/exchange/plugins/token_object.py @@ -41,6 +41,7 @@ 'op_get_asset_type_identifier', 'op_get_issuer_authority', 'op_get_authority', + 'op_get_balance', 'op_transfer', 'op_escrow', 'op_release', @@ -59,6 +60,7 @@ op_get_asset_type_identifier = asset_type.op_get_asset_type_identifier op_get_issuer_authority = vetting.op_get_issuer_authority op_get_authority = issuer.op_get_authority +op_get_balance = issuer.op_get_balance op_transfer = issuer.op_transfer op_escrow = issuer.op_escrow op_release = issuer.op_release @@ -312,6 +314,13 @@ def invoke(cls, state, context, new_owner, **kwargs) : with open (keyfile, "r") as myfile: verifying_key = myfile.read() + # in case count was specified, it must be 1 and we must remove it since it is set explicitly + # in the op invocation below + if 'count' in kwargs : + if kwargs['count'] != 1 : + raise ValueError('unexpected count for token transfer') + kwargs.pop('count') + session = pbuilder.SessionParameters(save_file=save_file) pcontract.invoke_contract_op(issuer.op_transfer, state, context, session, verifying_key, 1, **kwargs) @@ -372,6 +381,7 @@ def invoke(cls, state, context, message, **kwargs) : op_get_asset_type_identifier, op_get_issuer_authority, op_get_authority, + op_get_balance, op_transfer, op_escrow, op_release,