@wowok/agent-mcp 3.3.3 → 3.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/composition/compile.d.ts +4 -1
  2. package/dist/composition/compile.js +1 -1
  3. package/dist/evaluation/node-game.d.ts +3 -0
  4. package/dist/evaluation/node-game.js +1 -1
  5. package/dist/harness/recover.js +1 -1
  6. package/dist/knowledge/builtin-templates.d.ts +1 -1
  7. package/dist/knowledge/builtin-templates.js +1 -1
  8. package/dist/knowledge/guard-templates.d.ts +1 -1
  9. package/dist/knowledge/guard-templates.js +1 -1
  10. package/dist/knowledge/recipient-constraint.d.ts +9 -0
  11. package/dist/knowledge/recipient-constraint.js +1 -1
  12. package/dist/knowledge/scenario-modes.d.ts +1 -0
  13. package/dist/knowledge/template-loader.d.ts +1 -0
  14. package/dist/knowledge/template-loader.js +1 -1
  15. package/dist/knowledge/template-scanner.js +1 -1
  16. package/dist/participation/node-action-advisor.js +1 -1
  17. package/dist/playbooks/service-build/service-quote.js +1 -1
  18. package/dist/playbooks/service-build/service-quote.spec.js +1 -1
  19. package/dist/schema/call/base.d.ts +25 -0
  20. package/dist/schema/call/base.js +1 -1
  21. package/dist/schema/call/bridge.d.ts +1 -0
  22. package/dist/schema/call/error-codes.d.ts +1 -1
  23. package/dist/schema/call/error-codes.js +1 -1
  24. package/dist/schema/call/handler.js +1 -1
  25. package/dist/schema/call/order.d.ts +12 -0
  26. package/dist/schema/call/order.js +1 -1
  27. package/dist/schema/call/progress.js +1 -1
  28. package/dist/schema/call/semantic.js +1 -1
  29. package/dist/schema/local/index.d.ts +10 -0
  30. package/dist/schema/operations.d.ts +4 -0
  31. package/dist/schema/query/bi.d.ts +4 -0
  32. package/dist/schema/query/bi.js +1 -1
  33. package/dist/schema/query/index.d.ts +147 -0
  34. package/dist/schema/query/index.js +1 -1
  35. package/dist/schemas/account_operation.output.json +2 -1
  36. package/dist/schemas/bridge_operation.output.json +2 -1
  37. package/dist/schemas/index.json +1 -1
  38. package/dist/schemas/keeper_operation.output.json +1 -1
  39. package/dist/schemas/local_cache_operation.output.json +2 -1
  40. package/dist/schemas/local_history_operation.output.json +2 -1
  41. package/dist/schemas/local_info_operation.output.json +2 -1
  42. package/dist/schemas/local_mark_operation.output.json +2 -1
  43. package/dist/schemas/messenger_operation.output.json +1 -1
  44. package/dist/schemas/monitor_events.output.json +1 -1
  45. package/dist/schemas/monitor_subscription.output.json +1 -1
  46. package/dist/schemas/onchain_events.output.json +1 -1
  47. package/dist/schemas/onchain_operations.output.json +35 -4
  48. package/dist/schemas/onchain_operations.schema.json +21 -3
  49. package/dist/schemas/onchain_operations_order.schema.json +19 -1
  50. package/dist/schemas/onchain_operations_progress.schema.json +2 -2
  51. package/dist/schemas/onchain_table_data.output.json +2 -2
  52. package/dist/schemas/query_toolkit.output.json +17 -1
  53. package/dist/schemas/query_toolkit.schema.json +1 -1
  54. package/dist/schemas/wowok_buildin_info.output.json +259 -0
  55. package/dist/schemas/wowok_buildin_info.schema.json +121 -0
  56. package/dist/tools/build-fingerprint.d.ts +28 -0
  57. package/dist/tools/build-fingerprint.js +1 -0
  58. package/dist/tools/handlers/config.js +1 -1
  59. package/dist/tools/handlers/onchain.d.ts +6 -0
  60. package/dist/tools/handlers/onchain.js +1 -1
  61. package/dist/tools/handlers/query.js +1 -1
  62. package/dist/tools/handlers/review-chain.d.ts +9 -13
  63. package/dist/tools/handlers/review-chain.js +1 -1
  64. package/dist/tools/upgrade-check.d.ts +1 -0
  65. package/dist/tools/upgrade-check.js +1 -1
  66. package/package.json +2 -2
@@ -1 +1 @@
1
- import{buildAllocationAdvice,allocationAssessment}from'./allocation-advice.js';import{deriveGameContext}from'./game-context.js';import{counterpartyMoves}from'../knowledge/game-scenarios.js';import{evaluateNodeGame,actionAssessment}from'../evaluation/node-game.js';import{evaluateArbGame,moveAssessment}from'../evaluation/arbitration-game.js';import{resolveRoleIntent}from'../role/intent.js';import{analyzeMerchantInterest}from'./merchant-interest.js';import{analyzeCustomerInterest}from'./customer-interest.js';import{analyzeSupplierInterest}from'./supplier-interest.js';import{analyzeCollaboratorInterest}from'./collaborator-interest.js';function rawStr(a){if(a==null)return undefined;if(typeof a==='object'&&'balance'in a)return rawStr(a['balance']);return String(a);}export function buildNodeActionAdvice(b){const c=b['radar'],d=deriveGameContext({'has_order':c['order']!=null,'completed':b['completed'],'refunded':b['refunded'],'dispute_active':b['dispute_active'],'focus_object':c['progress'],'last_progress_at':b['last_progress_at'],'now':b['now']}),f={'role':c['perspective'],'context':d,'kernels_run':[],'advisory_gaps':[],'actions':[]},g=new Set(d['action_surface']),h=d['time_anchors']['stalled_hours'],i=b['completed']?'completed':b['refunded']?'refunded':null,j={'account':c['account'],'current_node':c['current_node'],'operable':c['operable'],'waiting_on':c['waiting_on'],'terminal':i,'stalled_hours':h,'unread_messages':b['unread_messages']};switch(c['perspective']){case'merchant':f['interest_analysis']=analyzeMerchantInterest({...j,'order_amount':rawStr(b['order_amount']),'token_type':b['token_type'],'allocation':b['allocation_summary'],'compensation_fund':rawStr(b['compensation_fund']),'arbitration_bound':b['arbitration_bound'],'rewards_count':b['rewards_count']??0x0});break;case'supplier':f['interest_analysis']=analyzeSupplierInterest({...j,'order_amount':rawStr(b['order_amount']),'token_type':b['token_type'],'arbitration_bound':b['arbitration_bound'],'compensation_fund':rawStr(b['compensation_fund']),'allocation_payoff':b['allocation_summary']?.['payoffs']});break;case'collaborator':f['interest_analysis']=analyzeCollaboratorInterest({...j,'collaborator_kind':c['collaborator_kind'],'arbitration_bound':b['arbitration_bound'],'allocation_payoff':b['allocation_summary']?.['payoffs']});break;case'customer':f['interest_analysis']=analyzeCustomerInterest({...j,'order_amount':rawStr(b['order_amount']),'token_type':b['token_type'],'compensation_fund':rawStr(b['compensation_fund']),'arbitration_bound':b['arbitration_bound'],'allocation_payoff':b['allocation_summary']?.['payoffs']});break;default:break;}const k=resolveRoleIntent(c['perspective'],b['persona_drive'],b['intent_hints']);for(const o of k['warnings'])f['advisory_gaps']['push'](o);if(g['has']('node_game')&&!c['workflow_unknown']){const p={'current_node':c['current_node'],'perspective':c['perspective'],'appetite':k['profile']['risk_appetite'],...k['profile']['red_lines']['length']?{'requirements':k['profile']['red_lines']}:{},'threshold':c['threshold'],'order_amount':rawStr(b['order_amount']),'compensation_fund':rawStr(b['compensation_fund']),'operable':c['operable']['map'](q=>({'name':q['name'],'to_node':q['to_node'],'execution_path':q['execution_path'],'guard':q['guard'],'consequence':q['consequence'],'weight':q['weight']})),'waiting_on':c['waiting_on']};f['node_game']=evaluateNodeGame(p);}if(d['dispute_active']&&b['arb_status']!=null){const q=c['perspective']==='customer'||c['perspective']==='merchant'||c['perspective']==='arbitrator'?c['perspective']:null;q&&(f['arb_game']=evaluateArbGame(b['arb_status'],q));}let l;if(c['order']!=null&&b['allocation_pool']){const r={'pool':b['allocation_pool'],'order_amount':b['order_amount'],'role':c['perspective'],'is_order_holder':b['is_order_holder'],'completed':b['completed'],'refunded':b['refunded'],'can_act_now':c['operable']['length']>0x0,'compensation_fund':b['compensation_fund'],'has_dispute':b['has_dispute']};try{l=buildAllocationAdvice(r);}catch(s){l=undefined,f['advisory_gaps']['push']('Fund\x20advice\x20failed\x20for\x20'+b['allocation_pool']['address']+':\x20'+s['message']+'.');}}if(l)f['fund_advice']=l;if(f['node_game'])f['kernels_run']['push']('node_game');if(f['arb_game'])f['kernels_run']['push']('arbitration_game');if(l)f['kernels_run']['push']('allocation_advice');const m=counterpartyMoves(c['perspective'],d['phase'])['map'](t=>t['attack_role']+':\x20'+t['move']),n=[c['progress'],...c['order']?[c['order']]:[]];if(f['node_game'])for(const t of f['node_game']['actions']){const u=c['operable']['find'](v=>v['name']===t['forward']);f['actions']['push']({'action':'advance\x20\x27'+t['forward']+'\x27\x20→\x20\x27'+t['to_node']+'\x27','via':u?.['recommended_call']?u['recommended_call']['tool']+'\x20('+u['recommended_call']['path']+')':'forward\x20execution\x20on\x20the\x20Progress\x20object','preconditions':[...t['guard']?['a\x20validated\x20passport\x20for\x20the\x20bound\x20guard']:[],...f['node_game']['cooperation']&&f['node_game']['cooperation']['needed_from_others']>0x0?[f['node_game']['cooperation']['needed_from_others']+'\x20more\x20forward-weight\x20from\x20cooperating\x20role(s)']:[]],'assessment':actionAssessment(t,f['node_game']),...d['time_anchors']['stalled_hours']!=null&&stalledCost(d['time_anchors']['stalled_hours'])!==undefined?{'cost_of_delay':stalledCost(d['time_anchors']['stalled_hours'])}:{},'counterparty_moves':m,'evidence_refs':[...n,t['forward']]});}if(f['arb_game'])for(const v of f['arb_game']['actions']){f['actions']['push']({'action':'case\x20move\x20\x27'+v['action']+'\x27\x20('+f['arb_game']['status']+')','via':'arbitration\x20case\x20operation\x20on\x20the\x20Arb\x20object','preconditions':[],'assessment':moveAssessment(v),'counterparty_moves':m,'evidence_refs':[...n,f['arb_game']['status']]});}return l&&l['decision_advice']['length']>0x0&&f['actions']['push']({'action':l['settled']?'review\x20the\x20settlement\x20state\x20of\x20the\x20allocation\x20pool':'move\x20on\x20the\x20allocation\x20pool\x20(settle\x20/\x20dispute\x20per\x20your\x20side\x27s\x20decision\x20rule)','via':'allocation\x20guard\x20mechanism\x20(alloc\x20by\x20guard)\x20/\x20dispute\x20filing','preconditions':[...l['funded']?['pool\x20still\x20holds\x20a\x20distributable\x20balance']:[],...l['settled']?[]:['no\x20Payment\x20produced\x20yet']],'assessment':allocationAssessment(l,{...h!=null&&h>0x18?{'costOfDelay':'order\x20stalled\x20'+Math['round'](h)+'h\x20—\x20the\x20pool\x20stays\x20frozen\x20while\x20you\x20wait'}:{},...rawStr(b['order_amount'])!==undefined?{'stake':rawStr(b['order_amount'])}:{}}),'counterparty_moves':m,'evidence_refs':[...n,...l['pool']?[l['pool']]:[]]}),f;}function stalledCost(a){if(a<=0x18)return undefined;return'order\x20has\x20not\x20advanced\x20for\x20'+Math['round'](a)+'h\x20—\x20leverage\x20and\x20evidence\x20decay\x20with\x20time';}
1
+ import{buildAllocationAdvice,allocationAssessment}from'./allocation-advice.js';import{deriveGameContext}from'./game-context.js';import{counterpartyMoves}from'../knowledge/game-scenarios.js';import{evaluateNodeGame,actionAssessment}from'../evaluation/node-game.js';import{evaluateArbGame,moveAssessment}from'../evaluation/arbitration-game.js';import{resolveRoleIntent}from'../role/intent.js';import{analyzeMerchantInterest}from'./merchant-interest.js';import{analyzeCustomerInterest}from'./customer-interest.js';import{analyzeSupplierInterest}from'./supplier-interest.js';import{analyzeCollaboratorInterest}from'./collaborator-interest.js';function rawStr(a){if(a==null)return undefined;if(typeof a==='object'&&'balance'in a)return rawStr(a['balance']);return String(a);}export function buildNodeActionAdvice(b){const c=b['radar'],d=deriveGameContext({'has_order':c['order']!=null,'completed':b['completed'],'refunded':b['refunded'],'dispute_active':b['dispute_active'],'focus_object':c['progress'],'last_progress_at':b['last_progress_at'],'now':b['now']}),f={'role':c['perspective'],'context':d,'kernels_run':[],'advisory_gaps':[],'actions':[]},g=new Set(d['action_surface']),h=d['time_anchors']['stalled_hours'],i=b['completed']?'completed':b['refunded']?'refunded':null,j={'account':c['account'],'current_node':c['current_node'],'operable':c['operable'],'waiting_on':c['waiting_on'],'terminal':i,'stalled_hours':h,'unread_messages':b['unread_messages']};switch(c['perspective']){case'merchant':f['interest_analysis']=analyzeMerchantInterest({...j,'order_amount':rawStr(b['order_amount']),'token_type':b['token_type'],'allocation':b['allocation_summary'],'compensation_fund':rawStr(b['compensation_fund']),'arbitration_bound':b['arbitration_bound'],'rewards_count':b['rewards_count']??0x0});break;case'supplier':f['interest_analysis']=analyzeSupplierInterest({...j,'order_amount':rawStr(b['order_amount']),'token_type':b['token_type'],'arbitration_bound':b['arbitration_bound'],'compensation_fund':rawStr(b['compensation_fund']),'allocation_payoff':b['allocation_summary']?.['payoffs']});break;case'collaborator':f['interest_analysis']=analyzeCollaboratorInterest({...j,'collaborator_kind':c['collaborator_kind'],'arbitration_bound':b['arbitration_bound'],'allocation_payoff':b['allocation_summary']?.['payoffs']});break;case'customer':f['interest_analysis']=analyzeCustomerInterest({...j,'order_amount':rawStr(b['order_amount']),'token_type':b['token_type'],'compensation_fund':rawStr(b['compensation_fund']),'arbitration_bound':b['arbitration_bound'],'allocation_payoff':b['allocation_summary']?.['payoffs']});break;default:break;}const k=resolveRoleIntent(c['perspective'],b['persona_drive'],b['intent_hints']);for(const o of k['warnings'])f['advisory_gaps']['push'](o);if(g['has']('node_game')&&!c['workflow_unknown']){const p={'current_node':c['current_node'],'perspective':c['perspective'],'appetite':k['profile']['risk_appetite'],...k['profile']['red_lines']['length']?{'requirements':k['profile']['red_lines']}:{},'threshold':c['threshold'],'order_amount':rawStr(b['order_amount']),'compensation_fund':rawStr(b['compensation_fund']),'claimable_rewards':c['pending_claims']['filter'](q=>q['kind']==='reward')['map'](q=>({'description':q['label']})),'operable':c['operable']['map'](q=>({'name':q['name'],'to_node':q['to_node'],'execution_path':q['execution_path'],'guard':q['guard'],'consequence':q['consequence'],'weight':q['weight']})),'waiting_on':c['waiting_on']};f['node_game']=evaluateNodeGame(p);}if(d['dispute_active']&&b['arb_status']!=null){const q=c['perspective']==='customer'||c['perspective']==='merchant'||c['perspective']==='arbitrator'?c['perspective']:null;q&&(f['arb_game']=evaluateArbGame(b['arb_status'],q));}let l;if(c['order']!=null&&b['allocation_pool']){const r={'pool':b['allocation_pool'],'order_amount':b['order_amount'],'role':c['perspective'],'is_order_holder':b['is_order_holder'],'completed':b['completed'],'refunded':b['refunded'],'can_act_now':c['operable']['length']>0x0,'compensation_fund':b['compensation_fund'],'has_dispute':b['has_dispute']};try{l=buildAllocationAdvice(r);}catch(s){l=undefined,f['advisory_gaps']['push']('Fund\x20advice\x20failed\x20for\x20'+b['allocation_pool']['address']+':\x20'+s['message']+'.');}}if(l)f['fund_advice']=l;if(f['node_game'])f['kernels_run']['push']('node_game');if(f['arb_game'])f['kernels_run']['push']('arbitration_game');if(l)f['kernels_run']['push']('allocation_advice');const m=counterpartyMoves(c['perspective'],d['phase'])['map'](t=>t['attack_role']+':\x20'+t['move']),n=[c['progress'],...c['order']?[c['order']]:[]];if(f['node_game'])for(const t of f['node_game']['actions']){const u=c['operable']['find'](v=>v['name']===t['forward']);f['actions']['push']({'action':'advance\x20\x27'+t['forward']+'\x27\x20→\x20\x27'+t['to_node']+'\x27','via':u?.['recommended_call']?u['recommended_call']['tool']+'\x20('+u['recommended_call']['path']+')':'forward\x20execution\x20on\x20the\x20Progress\x20object','preconditions':[...t['guard']?['a\x20validated\x20passport\x20for\x20the\x20bound\x20guard']:[],...f['node_game']['cooperation']&&f['node_game']['cooperation']['needed_from_others']>0x0?[f['node_game']['cooperation']['needed_from_others']+'\x20more\x20forward-weight\x20from\x20cooperating\x20role(s)']:[]],'assessment':actionAssessment(t,f['node_game']),...d['time_anchors']['stalled_hours']!=null&&stalledCost(d['time_anchors']['stalled_hours'])!==undefined?{'cost_of_delay':stalledCost(d['time_anchors']['stalled_hours'])}:{},'counterparty_moves':m,'evidence_refs':[...n,t['forward']]});}if(f['arb_game'])for(const v of f['arb_game']['actions']){f['actions']['push']({'action':'case\x20move\x20\x27'+v['action']+'\x27\x20('+f['arb_game']['status']+')','via':'arbitration\x20case\x20operation\x20on\x20the\x20Arb\x20object','preconditions':[],'assessment':moveAssessment(v),'counterparty_moves':m,'evidence_refs':[...n,f['arb_game']['status']]});}return l&&l['decision_advice']['length']>0x0&&f['actions']['push']({'action':l['settled']?'review\x20the\x20settlement\x20state\x20of\x20the\x20allocation\x20pool':'move\x20on\x20the\x20allocation\x20pool\x20(settle\x20/\x20dispute\x20per\x20your\x20side\x27s\x20decision\x20rule)','via':'allocation\x20guard\x20mechanism\x20(alloc\x20by\x20guard)\x20/\x20dispute\x20filing','preconditions':[...l['funded']?['pool\x20still\x20holds\x20a\x20distributable\x20balance']:[],...l['settled']?[]:['no\x20Payment\x20produced\x20yet']],'assessment':allocationAssessment(l,{...h!=null&&h>0x18?{'costOfDelay':'order\x20stalled\x20'+Math['round'](h)+'h\x20—\x20the\x20pool\x20stays\x20frozen\x20while\x20you\x20wait'}:{},...rawStr(b['order_amount'])!==undefined?{'stake':rawStr(b['order_amount'])}:{}}),'counterparty_moves':m,'evidence_refs':[...n,...l['pool']?[l['pool']]:[]]}),f;}function stalledCost(a){if(a<=0x18)return undefined;return'order\x20has\x20not\x20advanced\x20for\x20'+Math['round'](a)+'h\x20—\x20leverage\x20and\x20evidence\x20decay\x20with\x20time';}
@@ -1 +1 @@
1
- import{Config,LocalMark,query_objects,query_serviceContext}from'@wowok/wowok';import{resolveAddress as a352a}from'../../tools/handlers/name-resolution.js';import{formatMoneyAnnotation}from'./facet-money.js';const balanceStr=a=>a===null||a===undefined?'0':typeof a==='bigint'?a['toString']():String(a);async function displayOf(a,b,c){try{return(await formatMoneyAnnotation(a,b,c))['display'];}catch{return a;}}function describeRecipient(a){if(typeof a==='string')return a;if(a&&typeof a==='object'){const b=a;if('GuardIdentifier'in b)return'submission\x20slot\x20'+String(b['GuardIdentifier']);if('Entity'in b){const c=b['Entity'],d=c&&typeof c==='object'?c['name_or_address']:c;return d===''?'Entity(\x22\x22)\x20—\x20MCP\x20default\x20local\x20account':'Entity:'+String(d);}return JSON['stringify'](a);}return'unknown';}export async function handleServiceQuote(a){const b=a['context_network']??undefined??await Config['Instance']()['network_get'](),d=await a352a(a['service_address'],'service_address'),f=await query_serviceContext({'service':d,'network':b}),h=f['service'];if(!h)throw new Error('Service\x20\x27'+a['service_address']+'\x27\x20not\x20found\x20on\x20network\x20'+b+'.');const i=h?.['type_raw']??h?.['type']??'',j=i['match'](/<(.+)>$/),k=j?j[0x1]:null,l=Array['isArray'](h['sales'])?h['sales']:[],m=new Map();for(const J of l){if(!J||typeof J['name']!=='string')continue;m['set'](J['name'],{'price':balanceStr(J['price']?.['balance']??J['price']??0x0),'suspended':J['suspension']===!![]});}const n=a['items']??[...m['keys']()]['map'](K=>({'name':K,'quantity':0x1})),p=n['filter'](K=>!m['has'](K['name']));if(p['length']>0x0)throw new Error('Sale(s)\x20not\x20found\x20on\x20this\x20Service:\x20'+p['map'](K=>'\x27'+K['name']+'\x27')['join'](',\x20')+'.\x20'+('Available\x20sales:\x20'+([...m['keys']()]['map'](K=>'\x27'+K+'\x27')['join'](',\x20')||'<none>')+'.'));if(n['length']===0x0)throw new Error('This\x20Service\x20has\x20NO\x20configured\x20sales\x20—\x20nothing\x20to\x20quote.');const q=[];let t=0x0n;for(const K of n){const L=m['get'](K['name']),M=BigInt(L['price']||'0'),N=M*BigInt(K['quantity']);t+=N,q['push']({'name':K['name'],'quantity':K['quantity'],'unit_price':L['price'],'unit_price_display':await displayOf(L['price'],k,b),'line_total':N['toString'](),'suspended':L['suspended']});}let u=t,w=null;if(typeof a['discount']==='string'&&a['discount']['trim']()!==''){const O=await a352a(a['discount'],'discount');let P=null;try{const a0=await query_objects({'objects':[O],'network':b});P=a0?.['objects']?.[0x0]??null;}catch{P=null;}if(!P)throw new Error('E_DISCOUNT_NOT_FOUND:\x20coupon\x20\x27'+O+'\x27\x20not\x20found\x20—\x20it\x20was\x20already\x20burned\x20on\x20a\x20'+'previous\x20buy\x20(a\x20burned\x20coupon\x20is\x20destroyed\x20on\x20chain\x20and\x20cannot\x20be\x20quoted\x20again)\x20'+'or\x20the\x20address\x20is\x20wrong.\x20Re-quote\x20without\x20the\x20coupon.');const Q=String(P['service']??'');if(Q['toLowerCase']()!==d['toLowerCase']())throw new Error('E_SERVICE_DISCOUNT_NOT_MATCH:\x20coupon\x20\x27'+O+'\x27\x20is\x20bound\x20to\x20service\x20'+((Q||'<unparseable>')+',\x20not\x20to\x20'+d+'.\x20A\x20buy\x20with\x20this\x20coupon\x20aborts.'));const R=a1=>{const a2=balanceStr(a1)['trim']();return/^\d+$/['test'](a2)?BigInt(a2):0x0n;},S=BigInt(Date['now']()),T=R(P['time_start']),U=R(P['time_end']);if(S<T||S>U)throw new Error('E_DISCOUNT_TIME_INVALID:\x20coupon\x20\x27'+O+'\x27\x20is\x20valid\x20'+(T+'–'+U+'\x20(ms\x20epoch),\x20now\x20is\x20'+S+'.\x20A\x20buy\x20with\x20this\x20coupon\x20aborts.'));const V=Number(P['discount_type'])===0x0,W=R(P['off']),X=P['benchmark']===null||P['benchmark']===undefined?null:R(P['benchmark']),Y=X===null?!![]:t>=X;let Z=![];Y&&(Z=!![],u=V?t-t*W/0x2710n:t>W?t-W:0x0n),w={'coupon':O,'name':typeof P['name']==='string'?P['name']:null,'type':V?'rates':'minus','off':W['toString'](),'benchmark':X===null?null:X['toString'](),'benchmark_met':Y,'applied':Z,'list_total':t['toString'](),'final_total':u['toString'](),'final_total_display':await displayOf(u['toString'](),k,b),'note':Z?u===0x0n?'DEAD\x20BASKET\x20(F-BS-75):\x20the\x20coupon\x20covers\x20the\x20entire\x20basket,\x20but\x20the\x20chain\x20REFUSES\x20zero-total\x20'+'buys\x20—\x20the\x20client\x20gate\x20(order_new_zero_total_dead_order)\x20and\x20the\x20on-chain\x20zero-total\x20gate\x20'+'(abort\x2042)\x20both\x20reject\x20this\x20buy;\x20NOTHING\x20is\x20purchasable\x20at\x20total\x200,\x20free\x20product\x20or\x20not.\x20'+'Lower\x20the\x20coupon\x20value\x20so\x20the\x20final\x20total\x20stays\x20>=\x201\x20smallest\x20unit\x20(or\x20price\x20a\x20deliberate\x20'+'free\x20tier\x20at\x201\x20smallest\x20unit).\x20allow_zero_total\x20on\x20the\x20coupon\x20is\x20disclosure-only\x20and\x20does\x20'+'NOT\x20unlock\x20this\x20buy\x20(F-BS-74).':'Discounted\x20total\x20shown\x20—\x20order_new.buy.total_pay.balance\x20must\x20equal\x20final_total.':'⚠\x20Benchmark\x20NOT\x20met\x20(list\x20total\x20'+t+'\x20<\x20'+X+'):\x20the\x20chain\x20REJECTS\x20this\x20buy\x20when\x20the\x20coupon\x20is\x20attached\x20(error\x2038\x20—\x20full\x20rollback,\x20nothing\x20paid,\x20coupon\x20preserved).\x20Raise\x20the\x20basket\x20to\x20>=\x20'+X+',\x20or\x20order\x20without\x20the\x20coupon\x20and\x20keep\x20it.'};}const x=balanceStr(h['compensation_fund']??0x0),y=/^\d+$/['test'](x['trim']())?BigInt(x['trim']()):0x0n,z=0x3n*u,A={'fund_balance':y['toString'](),'fund_balance_display':await displayOf(y['toString'](),k,b),'required_for_this_basket':z['toString'](),'required_display':await displayOf(z['toString'](),k,b),'covered':y>=z,'note':y===0x0n?'This\x20Service\x20runs\x20WITHOUT\x20a\x20compensation\x20fund\x20—\x20a\x20legitimate\x20merchant\x20choice,\x20never\x20blocked\x20at\x20buy.\x20An\x20arbitration\x20award\x20beyond\x20the\x20pool\x20aborts\x20the\x20buyer\x27s\x20payout\x20(code\x2027,\x20claim\x20NOT\x20consumed)\x20and\x20waits\x20on\x20the\x20merchant\x20wallet.':y>=z?'The\x20fund\x20covers\x203x\x20this\x20basket\x27s\x20amount\x20—\x20a\x20single\x20ruling\x20at\x20the\x20maximum\x20award\x20multiple\x20is\x20payable\x20from\x20the\x20pool.':'BELOW\x20the\x20per-order\x20payout\x20requirement:\x20order\x20creation\x20will\x20be\x20BLOCKED\x20(compensation_fund_below_order_ceiling\x20—\x20no\x20money\x20moves)\x20until\x20the\x20merchant\x20tops\x20up\x20via\x20service.compensation_fund_add\x20to\x20>=\x203x\x20this\x20basket.'},B=await displayOf(u['toString'](),k,b),C=h['order_allocators'],D=Array['isArray'](C?.['allocators'])?C['allocators']:[],E=D['length']>0x0?D[0x0]:undefined,F=E?{'allocator_index':0x0,'note':'Sharing\x20rows\x20of\x20the\x20FIRST\x20order_allocator\x20(index\x200\x20—\x20NOT\x20necessarily\x20the\x20normal\x20'+'payout\x20path:\x20services\x20that\x20ship\x20refund-first\x20rails\x20put\x20the\x20refund\x20track\x20at\x20index\x200,\x20'+'klk15\x20C-06).\x20Guards\x20select\x20per-case\x20allocators\x20(refund\x20/\x20damage\x20/\x20late-cancel),\x20so\x20'+'the\x20LIVE\x20split\x20depends\x20on\x20which\x20guard\x20passes\x20—\x20identify\x20the\x20settlement\x20allocator\x20'+'via\x20service_panorama\x20before\x20ordering.','sharing':(Array['isArray'](E['sharing'])?E['sharing']:[])['map'](a1=>({'recipient':describeRecipient(a1?.['who']),'mode':typeof a1?.['mode']==='string'?a1['mode']:null,'value':balanceStr(a1?.['sharing']?.['balance']??a1?.['sharing']??0x0)}))}:null,G=Array['isArray'](h['rewards'])?h['rewards']['filter'](a1=>typeof a1==='string'&&a1!==''):[];let H=null;if(G['length']>0x0){const a1=[],a2=[];let a3=[];try{const a4=await query_objects({'objects':G,'network':b});a3=Array['isArray'](a4?.['objects'])?a4['objects']:[];}catch(a5){a1['push']('Reward\x20lookup\x20failed\x20('+(a5 instanceof Error?a5['message']:String(a5))+')\x20—\x20reward\x20terms\x20NOT\x20verified;\x20do\x20not\x20rely\x20on\x20them.');}for(const a6 of G){const a7=a3['find'](ak=>typeof ak?.['object']==='string'&&ak['object']['toLowerCase']()===a6['toLowerCase']());if(!a7){a1['push']('Reward\x20\x27'+a6+'\x27\x20could\x20not\x20be\x20read\x20—\x20its\x20terms\x20are\x20unknown;\x20do\x20not\x20rely\x20on\x20it.');continue;}const a8=balanceStr(a7['balance']??0x0),a9=/^\d+$/['test'](a8)?BigInt(a8):0x0n,aa=[];let ab=0x0n,ac=![];for(const ak of Array['isArray'](a7['guards'])?a7['guards']:[]){const al=ak?.['amount'],am=al!=null&&(al['type']===0x1||al['type']==='Fixed'),an=ak?.['expiration_time'],ao=an==null?null:Number(an),ap=ao!=null&&Number['isFinite'](ao)?ao:null;if(am){const aq=balanceStr(al['value']??0x0),ar=/^\d+$/['test'](aq)?BigInt(aq):0x0n;if(ar>ab)ab=ar;aa['push']({'guard':String(ak?.['guard']??''),'amount_type':'fixed','amount':aq,'amount_display':await displayOf(aq,k,b),'expiration_time':ap,'expiration_display':ap!=null?new Date(ap)['toISOString']():null,'expired':ap!=null?Date['now']()>ap:null,'min_rating':null});}else ac=!![],aa['push']({'guard':String(ak?.['guard']??''),'amount_type':'guard_submission','amount':'submission\x20identifier\x20'+String(al?.['value']??'?'),'amount_display':null,'expiration_time':ap,'expiration_display':ap!=null?new Date(ap)['toISOString']():null,'expired':ap!=null?Date['now']()>ap:null,'min_rating':null});}const ad=Array['from'](new Set(aa['map'](as=>as['guard'])['filter'](as=>as!==''))),ae=new Map();if(ad['length']>0x0)try{const as=await query_objects({'objects':ad,'network':b});for(const at of Array['isArray'](as?.['objects'])?as['objects']:[]){if(typeof at?.['object']==='string')ae['set'](at['object']['toLowerCase'](),at);}}catch{a1['push']('Claim\x20guard\x20lookup\x20failed\x20—\x20rating\x20conditions\x20on\x20'+ad['length']+'\x20claim\x20guard(s)\x20NOT\x20verified;\x20do\x20not\x20promise\x20the\x20incentive.');}const af=(au,av=0x0)=>{if(!au||typeof au!=='object'||av>0x4)return null;if(au['root']&&Array['isArray'](au['table']))return au;for(const aw of Object['values'](au)){if(aw&&typeof aw==='object'){const ax=af(aw,av+0x1);if(ax)return ax;}}return null;},ag=(au,av)=>{const aw=au['table']['find'](ay=>ay?.['identifier']===av&&ay?.['b_submission']===![]);if(!aw)return null;const ax=typeof aw['value']==='number'?aw['value']:Number(String(aw['value']??''));return Number['isFinite'](ax)?ax:null;},ah=(au,av,aw=0x0)=>{if(!au||typeof au!=='object'||aw>0x18)return null;const ax=typeof au['type']==='string'?au['type']:'';if(ax==='logic_as_u256_greater_or_equal'||ax==='logic_as_u256_greater'||ax==='logic_as_u256_equal'){const ay=Array['isArray'](au['nodes'])?au['nodes']:[],az=ay[0x0];if(ay['length']>=0x2&&JSON['stringify'](az??{})['includes']('repository.data')){const aA=ay[ay['length']-0x1],aB=aA?.['type']==='identifier'?ag(av,Number(aA['identifier'])):typeof aA?.['value']==='number'?aA['value']:null;if(aB!=null){const aC=ax==='logic_as_u256_greater_or_equal'?'>=':ax==='logic_as_u256_greater'?'>':'==';return aC+'\x20'+aB;}}}for(const aD of Object['values'](au)){if(Array['isArray'](aD))for(const aE of aD){const aF=ah(aE,av,aw+0x1);if(aF)return aF;}else{if(aD&&typeof aD==='object'){const aG=ah(aD,av,aw+0x1);if(aG)return aG;}}}return null;};for(const au of aa){au['min_rating']=null;const av=ae['get'](au['guard']['toLowerCase']());if(!av)continue;let aw;try{aw=JSON['stringify'](av,(az,aA)=>aA instanceof Uint8Array?Buffer['from'](aA)['toString']('base64'):aA);}catch{continue;}if(!aw['includes']('\x22rating\x22'))continue;const ax=af(av),ay=ax?ah(ax['root'],ax):null;if(ay)au['min_rating']=ay;else{const az=aw['toLowerCase']();if(az['includes']('\x22like\x22'))au['min_rating']='like';else{if(az['includes']('\x22dislike\x22'))au['min_rating']='dislike';else au['min_rating']='unknown';}}}const ai=a9===0x0n?'Pool\x20is\x20EMPTY\x20—\x20any\x20claim\x20aborts\x20on-chain\x20on\x20the\x20reward\x20module\x27s\x20E_INSUFFICIENT_BALANCE\x20(not\x20the\x20allocation\x20module\x27s\x20same-named\x20constant);\x20do\x20not\x20budget\x20on\x20this\x20reward.':ac||ab===0x0n?null:'Pool\x20covers\x20~'+(a9/ab)['toString']()+'\x20further\x20claim(s)\x20at\x20the\x20largest\x20configured\x20per-claim\x20amount.',aj=aa['filter'](aA=>aA['min_rating']==='unknown')['length'];aj>0x0&&a1['push'](aj+'\x20claim(s)\x20gate\x20on\x20a\x20rating\x20condition\x20whose\x20polarity\x20could\x20not\x20be\x20parsed\x20'+'(min_rating=unknown)\x20—\x20read\x20the\x20claim\x20guard\x20before\x20promising\x20this\x20incentive\x20to\x20the\x20buyer'),a2['push']({'reward':a6,'description':typeof a7['description']==='string'?a7['description']:null,'pool_balance':a9['toString'](),'pool_balance_display':await displayOf(a9['toString'](),k,b),'record_count':Number['isFinite'](Number(a7['record_count']))?Number(a7['record_count']):0x0,'claims':aa,'coverage':ai});}H={'note':'Pre-order\x20reward\x20terms\x20for\x20every\x20Reward\x20hung\x20on\x20this\x20Service\x20(bound\x20at\x20build\x20time):\x20pool\x20balance,\x20'+'per-claim\x20amount\x20and\x20claim\x20windows.\x20A\x20claim\x20aborts\x20after\x20its\x20window\x20(E_GUARD_EXPIRED)\x20or\x20'+'against\x20an\x20empty\x20pool\x20(E_INSUFFICIENT_BALANCE)\x20—\x20never\x20budget\x20on\x20an\x20expired\x20or\x20empty\x20'+'reward.\x20Claiming\x20requires\x20passing\x20the\x20claim\x20guard\x27s\x20conditions.','rewards':a2,'data_gaps':a1};}let I=null;try{const aA=await LocalMark['Instance']()['list']({'address':d});I=aA?.[0x0]?.['name']??null;}catch{I=null;}return{'action':'service_quote','network':String(b),'service':{'address':d,'name':I},'payment_token':{'coin_type':k,'display_note':k?'Prices\x20and\x20the\x20order\x20total\x20are\x20denominated\x20in\x20this\x20token\x27s\x20smallest\x20units;\x20displays\x20convert\x20with\x20the\x20token\x27s\x20on-chain\x20precision.':'Payment\x20token\x20could\x20not\x20be\x20parsed\x20from\x20the\x20Service\x20type\x20—\x20raw\x20smallest\x20units\x20only,\x20precision\x20NOT\x20guessed.'},'items':q,'total_pay':{'balance':u['toString'](),'display':B,'note':u===0x0n?'DEAD\x20BASKET\x20(F-BS-75):\x20this\x20quote\x20totals\x20ZERO\x20—\x20the\x20chain\x20REFUSES\x20zero-total\x20buys\x20(client\x20'+'order_new_zero_total_dead_order,\x20on-chain\x20abort\x2042),\x20so\x20this\x20basket\x20cannot\x20be\x20purchased\x20at\x20'+'all.\x20Either\x20the\x20basket\x20contains\x20a\x20zero-priced\x20SKU\x20(permanently\x20unbuyable\x20—\x20F-BS-76;\x20the\x20'+'merchant\x20must\x20reprice\x20it\x20to\x20>=\x201\x20smallest\x20unit)\x20or\x20a\x20coupon\x20zeroes\x20it\x20(lower\x20the\x20coupon\x20'+'value).\x20Do\x20NOT\x20attempt\x20the\x20buy.':w?.['applied']?'Discounted\x20total\x20—\x20order_new.buy.total_pay.balance\x20must\x20equal\x20this\x20exactly\x20(the\x20on-chain\x20buy\x20aborts\x20on\x20any\x20drift;\x20the\x20coupon\x20is\x20consumed\x20at\x20buy).':'order_new.buy.total_pay.balance\x20must\x20equal\x20this\x20exactly\x20when\x20passed\x20explicitly\x20—\x20the\x20on-chain\x20buy\x20aborts\x20on\x20any\x20drift.\x20WITHOUT\x20a\x20discount\x20you\x20may\x20also\x20omit\x20total_pay\x20entirely:\x20the\x20buy\x20auto-derives\x20this\x20exact\x20total\x20(M-K17).'},'discount':w,'allocation_preview':F,'compensation_fund_coverage':A,'reward_terms':H};}
1
+ import{Config,LocalMark,query_objects,query_serviceContext}from'@wowok/wowok';import{resolveAddress as a352a}from'../../tools/handlers/name-resolution.js';import{formatMoneyAnnotation}from'./facet-money.js';const balanceStr=a=>a===null||a===undefined?'0':typeof a==='bigint'?a['toString']():String(a);async function displayOf(a,b,c){try{return(await formatMoneyAnnotation(a,b,c))['display'];}catch{return a;}}function describeRecipient(a){if(typeof a==='string')return a;if(a&&typeof a==='object'){const b=a;if('GuardIdentifier'in b)return'submission\x20slot\x20'+String(b['GuardIdentifier']);if('Entity'in b){const c=b['Entity'],d=c&&typeof c==='object'?c['name_or_address']:c;return d===''?'Entity(\x22\x22)\x20—\x20MCP\x20default\x20local\x20account':'Entity:'+String(d);}return JSON['stringify'](a);}return'unknown';}export async function handleServiceQuote(a){const b=a['context_network']??undefined??await Config['Instance']()['network_get'](),d=await a352a(a['service_address'],'service_address'),f=await query_serviceContext({'service':d,'network':b}),h=f['service'];if(!h)throw new Error('Service\x20\x27'+a['service_address']+'\x27\x20not\x20found\x20on\x20network\x20'+b+'.');const i=h?.['type_raw']??h?.['type']??'',j=i['match'](/<(.+)>$/),k=j?j[0x1]:null,l=Array['isArray'](h['sales'])?h['sales']:[],m=new Map();for(const L of l){if(!L||typeof L['name']!=='string')continue;m['set'](L['name'],{'price':balanceStr(L['price']?.['balance']??L['price']??0x0),'suspended':L['suspension']===!![]});}const n=a['items']??[...m['keys']()]['map'](M=>({'name':M,'quantity':0x1})),p=n['filter'](M=>!m['has'](M['name']));if(p['length']>0x0)throw new Error('Sale(s)\x20not\x20found\x20on\x20this\x20Service:\x20'+p['map'](M=>'\x27'+M['name']+'\x27')['join'](',\x20')+'.\x20'+('Available\x20sales:\x20'+([...m['keys']()]['map'](M=>'\x27'+M+'\x27')['join'](',\x20')||'<none>')+'.'));if(n['length']===0x0)throw new Error('This\x20Service\x20has\x20NO\x20configured\x20sales\x20—\x20nothing\x20to\x20quote.');const q=[];let t=0x0n;for(const M of n){const N=m['get'](M['name']),O=BigInt(N['price']||'0'),P=O*BigInt(M['quantity']);t+=P,q['push']({'name':M['name'],'quantity':M['quantity'],'unit_price':N['price'],'unit_price_display':await displayOf(N['price'],k,b),'line_total':P['toString'](),'suspended':N['suspended']});}let u=t,w=null;if(typeof a['discount']==='string'&&a['discount']['trim']()!==''){const Q=await a352a(a['discount'],'discount');let R=null;try{const a2=await query_objects({'objects':[Q],'network':b});R=a2?.['objects']?.[0x0]??null;}catch{R=null;}if(!R)throw new Error('E_DISCOUNT_NOT_FOUND:\x20coupon\x20\x27'+Q+'\x27\x20not\x20found\x20—\x20it\x20was\x20already\x20burned\x20on\x20a\x20'+'previous\x20buy\x20(a\x20burned\x20coupon\x20is\x20destroyed\x20on\x20chain\x20and\x20cannot\x20be\x20quoted\x20again)\x20'+'or\x20the\x20address\x20is\x20wrong.\x20Re-quote\x20without\x20the\x20coupon.');const S=String(R['service']??'');if(S['toLowerCase']()!==d['toLowerCase']())throw new Error('E_SERVICE_DISCOUNT_NOT_MATCH:\x20coupon\x20\x27'+Q+'\x27\x20is\x20bound\x20to\x20service\x20'+((S||'<unparseable>')+',\x20not\x20to\x20'+d+'.\x20A\x20buy\x20with\x20this\x20coupon\x20aborts.'));const T=a3=>{const a4=balanceStr(a3)['trim']();return/^\d+$/['test'](a4)?BigInt(a4):0x0n;},U=BigInt(Date['now']()),V=T(R['time_start']),W=T(R['time_end']);if(U<V||U>W)throw new Error('E_DISCOUNT_TIME_INVALID:\x20coupon\x20\x27'+Q+'\x27\x20is\x20valid\x20'+(V+'–'+W+'\x20(ms\x20epoch),\x20now\x20is\x20'+U+'.\x20A\x20buy\x20with\x20this\x20coupon\x20aborts.'));const X=Number(R['discount_type'])===0x0,Y=T(R['off']),Z=R['benchmark']===null||R['benchmark']===undefined?null:T(R['benchmark']),a0=Z===null?!![]:t>=Z;let a1=![];a0&&(a1=!![],u=X?t-t*Y/0x2710n:t>Y?t-Y:0x0n),w={'coupon':Q,'name':typeof R['name']==='string'?R['name']:null,'type':X?'rates':'minus','off':Y['toString'](),'benchmark':Z===null?null:Z['toString'](),'benchmark_met':a0,'applied':a1,'list_total':t['toString'](),'final_total':u['toString'](),'final_total_display':await displayOf(u['toString'](),k,b),'note':a1?u===0x0n?'DEAD\x20BASKET\x20(F-BS-75):\x20the\x20coupon\x20covers\x20the\x20entire\x20basket,\x20but\x20the\x20chain\x20REFUSES\x20zero-total\x20'+'buys\x20—\x20the\x20client\x20gate\x20(order_new_zero_total_dead_order)\x20and\x20the\x20on-chain\x20zero-total\x20gate\x20'+'(abort\x2042)\x20both\x20reject\x20this\x20buy;\x20NOTHING\x20is\x20purchasable\x20at\x20total\x200,\x20free\x20product\x20or\x20not.\x20'+'Lower\x20the\x20coupon\x20value\x20so\x20the\x20final\x20total\x20stays\x20>=\x201\x20smallest\x20unit\x20(or\x20price\x20a\x20deliberate\x20'+'free\x20tier\x20at\x201\x20smallest\x20unit).\x20allow_zero_total\x20on\x20the\x20coupon\x20is\x20disclosure-only\x20and\x20does\x20'+'NOT\x20unlock\x20this\x20buy\x20(F-BS-74).':'Discounted\x20total\x20shown\x20—\x20order_new.buy.total_pay.balance\x20must\x20equal\x20final_total.':'⚠\x20Benchmark\x20NOT\x20met\x20(list\x20total\x20'+t+'\x20<\x20'+Z+'):\x20the\x20chain\x20REJECTS\x20this\x20buy\x20when\x20the\x20coupon\x20is\x20attached\x20(error\x2038\x20—\x20full\x20rollback,\x20nothing\x20paid,\x20coupon\x20preserved).\x20Raise\x20the\x20basket\x20to\x20>=\x20'+Z+',\x20or\x20order\x20without\x20the\x20coupon\x20and\x20keep\x20it.'};}const x=balanceStr(h['compensation_fund']??0x0),y=/^\d+$/['test'](x['trim']())?BigInt(x['trim']()):0x0n,z=0x3n*u,A=y/0x3n,B=await displayOf(A['toString'](),k,b),C={'fund_balance':y['toString'](),'fund_balance_display':await displayOf(y['toString'](),k,b),'max_coverable_order':A['toString'](),'max_coverable_order_display':B,'required_for_this_basket':z['toString'](),'required_display':await displayOf(z['toString'](),k,b),'covered':y>=z,'note':y===0x0n?'This\x20Service\x20runs\x20WITHOUT\x20a\x20compensation\x20fund\x20—\x20a\x20legitimate\x20merchant\x20choice,\x20never\x20blocked\x20at\x20buy.\x20An\x20arbitration\x20award\x20beyond\x20the\x20pool\x20aborts\x20the\x20buyer\x27s\x20payout\x20(code\x2027,\x20claim\x20NOT\x20consumed)\x20and\x20waits\x20on\x20the\x20merchant\x20wallet.':y>=z?'The\x20fund\x20covers\x203x\x20this\x20basket\x27s\x20amount\x20—\x20a\x20single\x20ruling\x20at\x20the\x20maximum\x20award\x20multiple\x20is\x20payable\x20from\x20the\x20pool.\x20Storefront\x20ceiling:\x20no\x20order\x20above\x20'+B+'\x20(fund/3)\x20can\x20be\x20created\x20—\x20quote\x20a\x20bigger\x20basket\x20against\x20the\x20ceiling,\x20not\x20just\x20this\x20one.':'BELOW\x20the\x20per-order\x20payout\x20requirement:\x20order\x20creation\x20will\x20be\x20BLOCKED\x20(compensation_fund_below_order_ceiling\x20—\x20no\x20money\x20moves)\x20until\x20the\x20merchant\x20tops\x20up\x20via\x20service.compensation_fund_add\x20to\x20>=\x203x\x20this\x20basket.\x20Standing\x20ceiling:\x20orders\x20above\x20'+B+'\x20(fund/3)\x20are\x20refused\x20at\x20buy,\x20so\x20this\x20basket\x20is\x20only\x20the\x20latest\x20casualty\x20—\x20every\x20bigger\x20SKU\x20is\x20unbuyable\x20too.'},D=await displayOf(u['toString'](),k,b),E=h['order_allocators'],F=Array['isArray'](E?.['allocators'])?E['allocators']:[],G=F['length']>0x0?F[0x0]:undefined,H=G?{'allocator_index':0x0,'note':'Sharing\x20rows\x20of\x20the\x20FIRST\x20order_allocator\x20(index\x200\x20—\x20NOT\x20necessarily\x20the\x20normal\x20'+'payout\x20path:\x20services\x20that\x20ship\x20refund-first\x20rails\x20put\x20the\x20refund\x20track\x20at\x20index\x200,\x20'+'klk15\x20C-06).\x20Guards\x20select\x20per-case\x20allocators\x20(refund\x20/\x20damage\x20/\x20late-cancel),\x20so\x20'+'the\x20LIVE\x20split\x20depends\x20on\x20which\x20guard\x20passes\x20—\x20identify\x20the\x20settlement\x20allocator\x20'+'via\x20service_panorama\x20before\x20ordering.','sharing':(Array['isArray'](G['sharing'])?G['sharing']:[])['map'](a3=>({'recipient':describeRecipient(a3?.['who']),'mode':typeof a3?.['mode']==='string'?a3['mode']:null,'value':balanceStr(a3?.['sharing']?.['balance']??a3?.['sharing']??0x0)}))}:null,I=Array['isArray'](h['rewards'])?h['rewards']['filter'](a3=>typeof a3==='string'&&a3!==''):[];let J=null;if(I['length']>0x0){const a3=[],a4=[];let a5=[];try{const a6=await query_objects({'objects':I,'network':b});a5=Array['isArray'](a6?.['objects'])?a6['objects']:[];}catch(a7){a3['push']('Reward\x20lookup\x20failed\x20('+(a7 instanceof Error?a7['message']:String(a7))+')\x20—\x20reward\x20terms\x20NOT\x20verified;\x20do\x20not\x20rely\x20on\x20them.');}for(const a8 of I){const a9=a5['find'](am=>typeof am?.['object']==='string'&&am['object']['toLowerCase']()===a8['toLowerCase']());if(!a9){a3['push']('Reward\x20\x27'+a8+'\x27\x20could\x20not\x20be\x20read\x20—\x20its\x20terms\x20are\x20unknown;\x20do\x20not\x20rely\x20on\x20it.');continue;}const aa=balanceStr(a9['balance']??0x0),ab=/^\d+$/['test'](aa)?BigInt(aa):0x0n,ac=[];let ad=0x0n,ae=![];for(const am of Array['isArray'](a9['guards'])?a9['guards']:[]){const an=am?.['amount'],ao=an!=null&&(an['type']===0x1||an['type']==='Fixed'),ap=am?.['expiration_time'],aq=ap==null?null:Number(ap),ar=aq!=null&&Number['isFinite'](aq)?aq:null;if(ao){const as=balanceStr(an['value']??0x0),at=/^\d+$/['test'](as)?BigInt(as):0x0n;if(at>ad)ad=at;ac['push']({'guard':String(am?.['guard']??''),'amount_type':'fixed','amount':as,'amount_display':await displayOf(as,k,b),'expiration_time':ar,'expiration_display':ar!=null?new Date(ar)['toISOString']():null,'expired':ar!=null?Date['now']()>ar:null,'min_rating':null});}else ae=!![],ac['push']({'guard':String(am?.['guard']??''),'amount_type':'guard_submission','amount':'submission\x20identifier\x20'+String(an?.['value']??'?'),'amount_display':null,'expiration_time':ar,'expiration_display':ar!=null?new Date(ar)['toISOString']():null,'expired':ar!=null?Date['now']()>ar:null,'min_rating':null});}const af=Array['from'](new Set(ac['map'](au=>au['guard'])['filter'](au=>au!==''))),ag=new Map();if(af['length']>0x0)try{const au=await query_objects({'objects':af,'network':b});for(const av of Array['isArray'](au?.['objects'])?au['objects']:[]){if(typeof av?.['object']==='string')ag['set'](av['object']['toLowerCase'](),av);}}catch{a3['push']('Claim\x20guard\x20lookup\x20failed\x20—\x20rating\x20conditions\x20on\x20'+af['length']+'\x20claim\x20guard(s)\x20NOT\x20verified;\x20do\x20not\x20promise\x20the\x20incentive.');}const ah=(aw,ax=0x0)=>{if(!aw||typeof aw!=='object'||ax>0x4)return null;if(aw['root']&&Array['isArray'](aw['table']))return aw;for(const ay of Object['values'](aw)){if(ay&&typeof ay==='object'){const az=ah(ay,ax+0x1);if(az)return az;}}return null;},ai=(aw,ax)=>{const ay=aw['table']['find'](aA=>aA?.['identifier']===ax&&aA?.['b_submission']===![]);if(!ay)return null;const az=typeof ay['value']==='number'?ay['value']:Number(String(ay['value']??''));return Number['isFinite'](az)?az:null;},aj=(aw,ax,ay=0x0)=>{if(!aw||typeof aw!=='object'||ay>0x18)return null;const az=typeof aw['type']==='string'?aw['type']:'';if(az==='logic_as_u256_greater_or_equal'||az==='logic_as_u256_greater'||az==='logic_as_u256_equal'){const aA=Array['isArray'](aw['nodes'])?aw['nodes']:[],aB=aA[0x0];if(aA['length']>=0x2&&JSON['stringify'](aB??{})['includes']('repository.data')){const aC=aA[aA['length']-0x1],aD=aC?.['type']==='identifier'?ai(ax,Number(aC['identifier'])):typeof aC?.['value']==='number'?aC['value']:null;if(aD!=null){const aE=az==='logic_as_u256_greater_or_equal'?'>=':az==='logic_as_u256_greater'?'>':'==';return aE+'\x20'+aD;}}}for(const aF of Object['values'](aw)){if(Array['isArray'](aF))for(const aG of aF){const aH=aj(aG,ax,ay+0x1);if(aH)return aH;}else{if(aF&&typeof aF==='object'){const aI=aj(aF,ax,ay+0x1);if(aI)return aI;}}}return null;};for(const aw of ac){aw['min_rating']=null;const ax=ag['get'](aw['guard']['toLowerCase']());if(!ax)continue;let ay;try{ay=JSON['stringify'](ax,(aB,aC)=>aC instanceof Uint8Array?Buffer['from'](aC)['toString']('base64'):aC);}catch{continue;}if(!ay['includes']('\x22rating\x22'))continue;const az=ah(ax),aA=az?aj(az['root'],az):null;if(aA)aw['min_rating']=aA;else{const aB=ay['toLowerCase']();if(aB['includes']('\x22like\x22'))aw['min_rating']='like';else{if(aB['includes']('\x22dislike\x22'))aw['min_rating']='dislike';else aw['min_rating']='unknown';}}}const ak=ab===0x0n?'Pool\x20is\x20EMPTY\x20—\x20any\x20claim\x20aborts\x20on-chain\x20on\x20the\x20reward\x20module\x27s\x20E_INSUFFICIENT_BALANCE\x20(not\x20the\x20allocation\x20module\x27s\x20same-named\x20constant);\x20do\x20not\x20budget\x20on\x20this\x20reward.':ae||ad===0x0n?null:'Pool\x20covers\x20~'+(ab/ad)['toString']()+'\x20further\x20claim(s)\x20at\x20the\x20largest\x20configured\x20per-claim\x20amount.',al=ac['filter'](aC=>aC['min_rating']==='unknown')['length'];al>0x0&&a3['push'](al+'\x20claim(s)\x20gate\x20on\x20a\x20rating\x20condition\x20whose\x20polarity\x20could\x20not\x20be\x20parsed\x20'+'(min_rating=unknown)\x20—\x20read\x20the\x20claim\x20guard\x20before\x20promising\x20this\x20incentive\x20to\x20the\x20buyer'),a4['push']({'reward':a8,'description':typeof a9['description']==='string'?a9['description']:null,'pool_balance':ab['toString'](),'pool_balance_display':await displayOf(ab['toString'](),k,b),'record_count':Number['isFinite'](Number(a9['record_count']))?Number(a9['record_count']):0x0,'claims':ac,'coverage':ak});}J={'note':'Pre-order\x20reward\x20terms\x20for\x20every\x20Reward\x20hung\x20on\x20this\x20Service\x20(bound\x20at\x20build\x20time):\x20pool\x20balance,\x20'+'per-claim\x20amount\x20and\x20claim\x20windows.\x20A\x20claim\x20aborts\x20after\x20its\x20window\x20(E_GUARD_EXPIRED)\x20or\x20'+'against\x20an\x20empty\x20pool\x20(E_INSUFFICIENT_BALANCE)\x20—\x20never\x20budget\x20on\x20an\x20expired\x20or\x20empty\x20'+'reward.\x20Claiming\x20requires\x20passing\x20the\x20claim\x20guard\x27s\x20conditions.','rewards':a4,'data_gaps':a3};}let K=null;try{const aC=await LocalMark['Instance']()['list']({'address':d});K=aC?.[0x0]?.['name']??null;}catch{K=null;}return{'action':'service_quote','network':String(b),'service':{'address':d,'name':K},'payment_token':{'coin_type':k,'display_note':k?'Prices\x20and\x20the\x20order\x20total\x20are\x20denominated\x20in\x20this\x20token\x27s\x20smallest\x20units;\x20displays\x20convert\x20with\x20the\x20token\x27s\x20on-chain\x20precision.':'Payment\x20token\x20could\x20not\x20be\x20parsed\x20from\x20the\x20Service\x20type\x20—\x20raw\x20smallest\x20units\x20only,\x20precision\x20NOT\x20guessed.'},'items':q,'total_pay':{'balance':u['toString'](),'display':D,'note':u===0x0n?'DEAD\x20BASKET\x20(F-BS-75):\x20this\x20quote\x20totals\x20ZERO\x20—\x20the\x20chain\x20REFUSES\x20zero-total\x20buys\x20(client\x20'+'order_new_zero_total_dead_order,\x20on-chain\x20abort\x2042),\x20so\x20this\x20basket\x20cannot\x20be\x20purchased\x20at\x20'+'all.\x20Either\x20the\x20basket\x20contains\x20a\x20zero-priced\x20SKU\x20(permanently\x20unbuyable\x20—\x20F-BS-76;\x20the\x20'+'merchant\x20must\x20reprice\x20it\x20to\x20>=\x201\x20smallest\x20unit)\x20or\x20a\x20coupon\x20zeroes\x20it\x20(lower\x20the\x20coupon\x20'+'value).\x20Do\x20NOT\x20attempt\x20the\x20buy.':w?.['applied']?'Discounted\x20total\x20—\x20order_new.buy.total_pay.balance\x20must\x20equal\x20this\x20exactly\x20(the\x20on-chain\x20buy\x20aborts\x20on\x20any\x20drift;\x20the\x20coupon\x20is\x20consumed\x20at\x20buy).':'order_new.buy.total_pay.balance\x20must\x20equal\x20this\x20exactly\x20when\x20passed\x20explicitly\x20—\x20the\x20on-chain\x20buy\x20aborts\x20on\x20any\x20drift.\x20WITHOUT\x20a\x20discount\x20you\x20may\x20also\x20omit\x20total_pay\x20entirely:\x20the\x20buy\x20auto-derives\x20this\x20exact\x20total\x20(M-K17).'},'discount':w,'allocation_preview':H,'compensation_fund_coverage':C,'reward_terms':J};}
@@ -1 +1 @@
1
- import{describe,it,expect,vi,beforeEach}from'vitest';const {sdkMocks}=vi['hoisted'](()=>({'sdkMocks':{'network_get':vi['fn'](),'localMarkList':vi['fn'](),'query_objects':vi['fn'](),'query_serviceContext':vi['fn'](),'resolveAddress':vi['fn']()}}));vi['mock']('@wowok/wowok',async a=>{const b=await a();return{...b,'Config':{'Instance':()=>({'network_get':sdkMocks['network_get']})},'LocalMark':{'Instance':()=>({'list':sdkMocks['localMarkList']})},'query_objects':sdkMocks['query_objects'],'query_serviceContext':sdkMocks['query_serviceContext']};}),vi['mock']('../../tools/handlers/name-resolution.js',()=>({'resolveAddress':sdkMocks['resolveAddress']})),vi['mock']('./facet-money.js',()=>({'formatMoneyAnnotation':async a=>({'display':a})}));import{handleServiceQuote}from'./service-quote.js';const SVC='0x'+'1'['repeat'](0x40),COUPON='0x'+'2'['repeat'](0x40),OTHER_SVC='0x'+'3'['repeat'](0x40),FLEXIBLE='Flexible\x20—\x20canal\x20view\x20double',LIST_TOTAL=0x35a4e900n;function makeCoupon(a={}){const b=Date['now']();return{'object':COUPON,'name':'bk3t-promo15','discount_type':0x0,'off':0x5dc,'benchmark':null,'time_start':b-0x5265c00,'time_end':b+0x5265c00,'service':SVC,'transferable':![],...a};}function quoteInput(a={}){return{'query_type':'service_quote','service_address':'bk3t-canal-stay','items':[{'name':FLEXIBLE,'quantity':0x1}],'context_network':'mainnet',...a};}beforeEach(()=>{vi['clearAllMocks'](),sdkMocks['network_get']['mockResolvedValue']('mainnet'),sdkMocks['localMarkList']['mockResolvedValue']([{'name':'bk3t-canal-stay'}]),sdkMocks['query_serviceContext']['mockResolvedValue']({'service':{'type_raw':'Service<0x2::wow::WOW>','sales':[{'name':FLEXIBLE,'price':{'balance':LIST_TOTAL['toString']()},'suspension':![]}]}}),sdkMocks['resolveAddress']['mockImplementation'](async a=>{if(a==='bk3t-canal-stay')return SVC;if(a==='bk3t-promo15'||a===COUPON)return COUPON;throw new Error('unresolvable:\x20'+a);}),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon()]});}),describe('service_quote\x20discount\x20pricing\x20(F-10)',()=>{it('no\x20discount\x20requested\x20→\x20undiscounted\x20total,\x20discount\x20block\x20null\x20(pre-fix\x20behavior\x20preserved)',async()=>{const a=await handleServiceQuote(quoteInput());expect(a['discount'])['toBeNull'](),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());}),it('RATES\x20coupon\x20applies\x20with\x20integer\x20floor\x20division\x20—\x20reproduces\x20the\x20live\x20order\x20C\x20number',async()=>{const a=await handleServiceQuote(quoteInput({'discount':'bk3t-promo15'}));expect(a['discount'])['not']['toBeNull'](),expect(a['discount']['type'])['toBe']('rates'),expect(a['discount']['applied'])['toBe'](!![]),expect(a['discount']['list_total'])['toBe']('900000000'),expect(a['discount']['final_total'])['toBe']('765000000'),expect(a['total_pay']['balance'])['toBe']('765000000'),expect(a['total_pay']['note'])['toContain']('Discounted\x20total');}),it('MINUS\x20coupon\x20subtracts\x20a\x20fixed\x20amount\x20and\x20clamps\x20at\x20zero',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'discount_type':0x1,'off':0x5f5e100})]});const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['type'])['toBe']('minus'),expect(a['discount']['final_total'])['toBe']('800000000'),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'discount_type':0x1,'off':0x77359400})]});const b=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(b['discount']['final_total'])['toBe']('0'),expect(b['discount']['note'])['toContain']('DEAD\x20BASKET'),expect(b['discount']['note'])['toContain']('REFUSES\x20zero-total'),expect(b['discount']['note'])['toContain']('allow_zero_total'),expect(b['discount']['note'])['toContain']('NOT\x20unlock\x20this\x20buy'),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'discount_type':0x1,'off':0x5f5e100})]});const c=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(c['discount']['note'])['toBe']('Discounted\x20total\x20shown\x20—\x20order_new.buy.total_pay.balance\x20must\x20equal\x20final_total.');}),it('unmet\x20benchmark\x20→\x20applied:false\x20+\x20attach\x20warning,\x20total\x20stays\x20at\x20list\x20price\x20(NOT\x20thrown)',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'benchmark':(LIST_TOTAL+0x1n)['toString']()})]});const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['applied'])['toBe'](![]),expect(a['discount']['benchmark_met'])['toBe'](![]),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']()),expect(a['discount']['note'])['toContain']('REJECTS'),expect(a['discount']['note'])['toContain']('coupon\x20preserved');}),it('benchmark\x20exactly\x20met\x20→\x20applies\x20(chain\x20uses\x20>=)',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'benchmark':LIST_TOTAL['toString']()})]});const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['applied'])['toBe'](!![]),expect(a['discount']['final_total'])['toBe']('765000000');}),it('benchmark\x20None\x20always\x20applies\x20(corrected\x20old\x20docs\x20claim)',async()=>{const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['benchmark'])['toBeNull'](),expect(a['discount']['applied'])['toBe'](!![]);}),it('coupon\x20bound\x20to\x20another\x20service\x20→\x20rejected\x20like\x20the\x20chain\x20abort\x20(E_SERVICE_DISCOUNT_NOT_MATCH)',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'service':OTHER_SVC})]}),await expect(handleServiceQuote(quoteInput({'discount':COUPON})))['rejects']['toThrow'](/E_SERVICE_DISCOUNT_NOT_MATCH/);}),it('coupon\x20outside\x20its\x20time\x20window\x20→\x20rejected\x20like\x20the\x20chain\x20abort\x20(E_DISCOUNT_TIME_INVALID)',async()=>{const a=Date['now']();sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'time_start':a+0x3e8,'time_end':a+0x186a0})]}),await expect(handleServiceQuote(quoteInput({'discount':COUPON})))['rejects']['toThrow'](/E_DISCOUNT_TIME_INVALID/);}),it('unknown\x20coupon\x20object\x20→\x20clear\x20rejection,\x20never\x20a\x20silent\x20full-price\x20quote',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[]}),await expect(handleServiceQuote(quoteInput({'discount':COUPON})))['rejects']['toThrow'](/not found/);});});const REWARD='0x'+'4'['repeat'](0x40),CLAIM_GUARD='0x'+'5'['repeat'](0x40);function makeReward(a={}){return{'object':REWARD,'description':'5-star\x20review\x20reward','balance':'500000000','record_count':0x3,'guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x1,'value':'100000000'},'expiration_time':Date['now']()+0x5265c00}],...a};}function svcWithRewards(...a){sdkMocks['query_serviceContext']['mockResolvedValue']({'service':{'type_raw':'Service<0x2::wow::WOW>','sales':[{'name':FLEXIBLE,'price':{'balance':LIST_TOTAL['toString']()},'suspension':![]}],'rewards':a}});}describe('service_quote\x20reward\x20terms\x20(review\x20component\x20b2-5)',()=>{it('no\x20rewards\x20on\x20the\x20Service\x20→\x20reward_terms\x20null',async()=>{const a=await handleServiceQuote(quoteInput());expect(a['reward_terms'])['toBeNull']();}),it('fixed\x20amount\x20+\x20live\x20window\x20→\x20terms\x20with\x20coverage\x20estimate,\x20expired:false,\x20no\x20gaps',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward()]});const a=await handleServiceQuote(quoteInput());expect(a['reward_terms'])['not']['toBeNull']();const b=a['reward_terms']['rewards'][0x0];expect(b['reward'])['toBe'](REWARD),expect(b['description'])['toBe']('5-star\x20review\x20reward'),expect(b['pool_balance'])['toBe']('500000000'),expect(b['record_count'])['toBe'](0x3),expect(b['claims'][0x0]['guard'])['toBe'](CLAIM_GUARD),expect(b['claims'][0x0]['amount_type'])['toBe']('fixed'),expect(b['claims'][0x0]['amount'])['toBe']('100000000'),expect(b['claims'][0x0]['expired'])['toBe'](![]),expect(b['coverage'])['toMatch'](/~5 further claim/),expect(a['reward_terms']['data_gaps'])['toEqual']([]),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());}),it('empty\x20pool\x20→\x20EMPTY\x20coverage\x20warning;\x20expired\x20window\x20→\x20expired:true',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward({'balance':'0','guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x1,'value':'100000000'},'expiration_time':Date['now']()-0x3e8}]})]});const a=await handleServiceQuote(quoteInput()),b=a['reward_terms']['rewards'][0x0];expect(b['claims'][0x0]['expired'])['toBe'](!![]),expect(b['coverage'])['toContain']('EMPTY'),expect(b['coverage'])['toContain']('E_INSUFFICIENT_BALANCE');}),it('guard_submission\x20amount\x20→\x20coverage\x20null\x20(guard-decided),\x20amount\x20carries\x20the\x20submission\x20identifier',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward({'guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x0,'value':0x7}}]})]});const a=await handleServiceQuote(quoteInput()),b=a['reward_terms']['rewards'][0x0];expect(b['claims'][0x0]['amount_type'])['toBe']('guard_submission'),expect(b['claims'][0x0]['amount'])['toContain']('7'),expect(b['claims'][0x0]['amount_display'])['toBeNull'](),expect(b['coverage'])['toBeNull']();}),it('no\x20window\x20set\x20→\x20expiration\x20null\x20and\x20expired\x20null\x20(claimable\x20until\x20guard\x20removal)',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward({'guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x1,'value':'100000000'}}]})]});const a=await handleServiceQuote(quoteInput()),b=a['reward_terms']['rewards'][0x0]['claims'][0x0];expect(b['expiration_time'])['toBeNull'](),expect(b['expiration_display'])['toBeNull'](),expect(b['expired'])['toBeNull']();}),it('unreadable\x20reward\x20object\x20→\x20data_gaps\x20note,\x20quote\x20still\x20succeeds\x20(fail-soft)',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[]});const a=await handleServiceQuote(quoteInput());expect(a['reward_terms'])['not']['toBeNull'](),expect(a['reward_terms']['rewards'])['toEqual']([]),expect(a['reward_terms']['data_gaps'][0x0])['toContain'](REWARD),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());}),it('reward\x20lookup\x20throws\x20→\x20whole\x20lookup\x20degrades\x20to\x20one\x20gap\x20note,\x20never\x20thrown',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockRejectedValue'](new Error('rpc\x20down'));const a=await handleServiceQuote(quoteInput());expect(a['reward_terms']['rewards'])['toEqual']([]),expect(a['reward_terms']['data_gaps'][0x0])['toContain']('rpc\x20down'),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());});});function svcWithFund(a){sdkMocks['query_serviceContext']['mockResolvedValue']({'service':{'type_raw':'Service<0x2::wow::WOW>','sales':[{'name':FLEXIBLE,'price':{'balance':LIST_TOTAL['toString']()},'suspension':![]}],'compensation_fund':a}});}describe('service_quote\x20compensation_fund_coverage\x20(b6-11)',()=>{it('no\x20fund\x20→\x20covered:false\x20with\x20the\x20no-protection\x20disclosure\x20(never\x20blocked)',async()=>{const a=await handleServiceQuote(quoteInput());expect(a['compensation_fund_coverage'])['not']['toBeNull'](),expect(a['compensation_fund_coverage']['fund_balance'])['toBe']('0'),expect(a['compensation_fund_coverage']['required_for_this_basket'])['toBe']('2700000000'),expect(a['compensation_fund_coverage']['covered'])['toBe'](![]),expect(a['compensation_fund_coverage']['note'])['toContain']('WITHOUT\x20a\x20compensation\x20fund'),expect(a['compensation_fund_coverage']['note'])['toContain']('never\x20blocked');}),it('fund\x20at/over\x203x\x20the\x20basket\x20→\x20covered:true',async()=>{svcWithFund('2700000000');const a=await handleServiceQuote(quoteInput());expect(a['compensation_fund_coverage']['covered'])['toBe'](!![]),expect(a['compensation_fund_coverage']['note'])['toContain']('payable\x20from\x20the\x20pool');}),it('fund\x20short\x20→\x20covered:false\x20and\x20the\x20note\x20names\x20the\x20buy-time\x20block\x20+\x20error\x20code',async()=>{svcWithFund('100000000');const a=await handleServiceQuote(quoteInput());expect(a['compensation_fund_coverage']['covered'])['toBe'](![]),expect(a['compensation_fund_coverage']['note'])['toContain']('BLOCKED'),expect(a['compensation_fund_coverage']['note'])['toContain']('compensation_fund_below_order_ceiling'),expect(a['compensation_fund_coverage']['note'])['toContain']('compensation_fund_add');}),it('required\x20base\x20is\x20the\x20DISCOUNTED\x20total\x20(what\x20the\x20order\x20actually\x20pays)',async()=>{svcWithFund('2295000000');const a=await handleServiceQuote(quoteInput({'discount':'bk3t-promo15'}));expect(a['total_pay']['balance'])['toBe']('765000000'),expect(a['compensation_fund_coverage']['required_for_this_basket'])['toBe']('2295000000'),expect(a['compensation_fund_coverage']['covered'])['toBe'](!![]);});});
1
+ import{describe,it,expect,vi,beforeEach}from'vitest';const {sdkMocks}=vi['hoisted'](()=>({'sdkMocks':{'network_get':vi['fn'](),'localMarkList':vi['fn'](),'query_objects':vi['fn'](),'query_serviceContext':vi['fn'](),'resolveAddress':vi['fn']()}}));vi['mock']('@wowok/wowok',async a=>{const b=await a();return{...b,'Config':{'Instance':()=>({'network_get':sdkMocks['network_get']})},'LocalMark':{'Instance':()=>({'list':sdkMocks['localMarkList']})},'query_objects':sdkMocks['query_objects'],'query_serviceContext':sdkMocks['query_serviceContext']};}),vi['mock']('../../tools/handlers/name-resolution.js',()=>({'resolveAddress':sdkMocks['resolveAddress']})),vi['mock']('./facet-money.js',()=>({'formatMoneyAnnotation':async a=>({'display':a})}));import{handleServiceQuote}from'./service-quote.js';const SVC='0x'+'1'['repeat'](0x40),COUPON='0x'+'2'['repeat'](0x40),OTHER_SVC='0x'+'3'['repeat'](0x40),FLEXIBLE='Flexible\x20—\x20canal\x20view\x20double',LIST_TOTAL=0x35a4e900n;function makeCoupon(a={}){const b=Date['now']();return{'object':COUPON,'name':'bk3t-promo15','discount_type':0x0,'off':0x5dc,'benchmark':null,'time_start':b-0x5265c00,'time_end':b+0x5265c00,'service':SVC,'transferable':![],...a};}function quoteInput(a={}){return{'query_type':'service_quote','service_address':'bk3t-canal-stay','items':[{'name':FLEXIBLE,'quantity':0x1}],'context_network':'mainnet',...a};}beforeEach(()=>{vi['clearAllMocks'](),sdkMocks['network_get']['mockResolvedValue']('mainnet'),sdkMocks['localMarkList']['mockResolvedValue']([{'name':'bk3t-canal-stay'}]),sdkMocks['query_serviceContext']['mockResolvedValue']({'service':{'type_raw':'Service<0x2::wow::WOW>','sales':[{'name':FLEXIBLE,'price':{'balance':LIST_TOTAL['toString']()},'suspension':![]}]}}),sdkMocks['resolveAddress']['mockImplementation'](async a=>{if(a==='bk3t-canal-stay')return SVC;if(a==='bk3t-promo15'||a===COUPON)return COUPON;throw new Error('unresolvable:\x20'+a);}),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon()]});}),describe('service_quote\x20discount\x20pricing\x20(F-10)',()=>{it('no\x20discount\x20requested\x20→\x20undiscounted\x20total,\x20discount\x20block\x20null\x20(pre-fix\x20behavior\x20preserved)',async()=>{const a=await handleServiceQuote(quoteInput());expect(a['discount'])['toBeNull'](),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());}),it('RATES\x20coupon\x20applies\x20with\x20integer\x20floor\x20division\x20—\x20reproduces\x20the\x20live\x20order\x20C\x20number',async()=>{const a=await handleServiceQuote(quoteInput({'discount':'bk3t-promo15'}));expect(a['discount'])['not']['toBeNull'](),expect(a['discount']['type'])['toBe']('rates'),expect(a['discount']['applied'])['toBe'](!![]),expect(a['discount']['list_total'])['toBe']('900000000'),expect(a['discount']['final_total'])['toBe']('765000000'),expect(a['total_pay']['balance'])['toBe']('765000000'),expect(a['total_pay']['note'])['toContain']('Discounted\x20total');}),it('MINUS\x20coupon\x20subtracts\x20a\x20fixed\x20amount\x20and\x20clamps\x20at\x20zero',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'discount_type':0x1,'off':0x5f5e100})]});const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['type'])['toBe']('minus'),expect(a['discount']['final_total'])['toBe']('800000000'),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'discount_type':0x1,'off':0x77359400})]});const b=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(b['discount']['final_total'])['toBe']('0'),expect(b['discount']['note'])['toContain']('DEAD\x20BASKET'),expect(b['discount']['note'])['toContain']('REFUSES\x20zero-total'),expect(b['discount']['note'])['toContain']('allow_zero_total'),expect(b['discount']['note'])['toContain']('NOT\x20unlock\x20this\x20buy'),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'discount_type':0x1,'off':0x5f5e100})]});const c=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(c['discount']['note'])['toBe']('Discounted\x20total\x20shown\x20—\x20order_new.buy.total_pay.balance\x20must\x20equal\x20final_total.');}),it('unmet\x20benchmark\x20→\x20applied:false\x20+\x20attach\x20warning,\x20total\x20stays\x20at\x20list\x20price\x20(NOT\x20thrown)',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'benchmark':(LIST_TOTAL+0x1n)['toString']()})]});const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['applied'])['toBe'](![]),expect(a['discount']['benchmark_met'])['toBe'](![]),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']()),expect(a['discount']['note'])['toContain']('REJECTS'),expect(a['discount']['note'])['toContain']('coupon\x20preserved');}),it('benchmark\x20exactly\x20met\x20→\x20applies\x20(chain\x20uses\x20>=)',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'benchmark':LIST_TOTAL['toString']()})]});const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['applied'])['toBe'](!![]),expect(a['discount']['final_total'])['toBe']('765000000');}),it('benchmark\x20None\x20always\x20applies\x20(corrected\x20old\x20docs\x20claim)',async()=>{const a=await handleServiceQuote(quoteInput({'discount':COUPON}));expect(a['discount']['benchmark'])['toBeNull'](),expect(a['discount']['applied'])['toBe'](!![]);}),it('coupon\x20bound\x20to\x20another\x20service\x20→\x20rejected\x20like\x20the\x20chain\x20abort\x20(E_SERVICE_DISCOUNT_NOT_MATCH)',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'service':OTHER_SVC})]}),await expect(handleServiceQuote(quoteInput({'discount':COUPON})))['rejects']['toThrow'](/E_SERVICE_DISCOUNT_NOT_MATCH/);}),it('coupon\x20outside\x20its\x20time\x20window\x20→\x20rejected\x20like\x20the\x20chain\x20abort\x20(E_DISCOUNT_TIME_INVALID)',async()=>{const a=Date['now']();sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeCoupon({'time_start':a+0x3e8,'time_end':a+0x186a0})]}),await expect(handleServiceQuote(quoteInput({'discount':COUPON})))['rejects']['toThrow'](/E_DISCOUNT_TIME_INVALID/);}),it('unknown\x20coupon\x20object\x20→\x20clear\x20rejection,\x20never\x20a\x20silent\x20full-price\x20quote',async()=>{sdkMocks['query_objects']['mockResolvedValue']({'objects':[]}),await expect(handleServiceQuote(quoteInput({'discount':COUPON})))['rejects']['toThrow'](/not found/);});});const REWARD='0x'+'4'['repeat'](0x40),CLAIM_GUARD='0x'+'5'['repeat'](0x40);function makeReward(a={}){return{'object':REWARD,'description':'5-star\x20review\x20reward','balance':'500000000','record_count':0x3,'guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x1,'value':'100000000'},'expiration_time':Date['now']()+0x5265c00}],...a};}function svcWithRewards(...a){sdkMocks['query_serviceContext']['mockResolvedValue']({'service':{'type_raw':'Service<0x2::wow::WOW>','sales':[{'name':FLEXIBLE,'price':{'balance':LIST_TOTAL['toString']()},'suspension':![]}],'rewards':a}});}describe('service_quote\x20reward\x20terms\x20(review\x20component\x20b2-5)',()=>{it('no\x20rewards\x20on\x20the\x20Service\x20→\x20reward_terms\x20null',async()=>{const a=await handleServiceQuote(quoteInput());expect(a['reward_terms'])['toBeNull']();}),it('fixed\x20amount\x20+\x20live\x20window\x20→\x20terms\x20with\x20coverage\x20estimate,\x20expired:false,\x20no\x20gaps',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward()]});const a=await handleServiceQuote(quoteInput());expect(a['reward_terms'])['not']['toBeNull']();const b=a['reward_terms']['rewards'][0x0];expect(b['reward'])['toBe'](REWARD),expect(b['description'])['toBe']('5-star\x20review\x20reward'),expect(b['pool_balance'])['toBe']('500000000'),expect(b['record_count'])['toBe'](0x3),expect(b['claims'][0x0]['guard'])['toBe'](CLAIM_GUARD),expect(b['claims'][0x0]['amount_type'])['toBe']('fixed'),expect(b['claims'][0x0]['amount'])['toBe']('100000000'),expect(b['claims'][0x0]['expired'])['toBe'](![]),expect(b['coverage'])['toMatch'](/~5 further claim/),expect(a['reward_terms']['data_gaps'])['toEqual']([]),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());}),it('empty\x20pool\x20→\x20EMPTY\x20coverage\x20warning;\x20expired\x20window\x20→\x20expired:true',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward({'balance':'0','guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x1,'value':'100000000'},'expiration_time':Date['now']()-0x3e8}]})]});const a=await handleServiceQuote(quoteInput()),b=a['reward_terms']['rewards'][0x0];expect(b['claims'][0x0]['expired'])['toBe'](!![]),expect(b['coverage'])['toContain']('EMPTY'),expect(b['coverage'])['toContain']('E_INSUFFICIENT_BALANCE');}),it('guard_submission\x20amount\x20→\x20coverage\x20null\x20(guard-decided),\x20amount\x20carries\x20the\x20submission\x20identifier',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward({'guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x0,'value':0x7}}]})]});const a=await handleServiceQuote(quoteInput()),b=a['reward_terms']['rewards'][0x0];expect(b['claims'][0x0]['amount_type'])['toBe']('guard_submission'),expect(b['claims'][0x0]['amount'])['toContain']('7'),expect(b['claims'][0x0]['amount_display'])['toBeNull'](),expect(b['coverage'])['toBeNull']();}),it('no\x20window\x20set\x20→\x20expiration\x20null\x20and\x20expired\x20null\x20(claimable\x20until\x20guard\x20removal)',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[makeReward({'guards':[{'guard':CLAIM_GUARD,'amount':{'type':0x1,'value':'100000000'}}]})]});const a=await handleServiceQuote(quoteInput()),b=a['reward_terms']['rewards'][0x0]['claims'][0x0];expect(b['expiration_time'])['toBeNull'](),expect(b['expiration_display'])['toBeNull'](),expect(b['expired'])['toBeNull']();}),it('unreadable\x20reward\x20object\x20→\x20data_gaps\x20note,\x20quote\x20still\x20succeeds\x20(fail-soft)',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockResolvedValue']({'objects':[]});const a=await handleServiceQuote(quoteInput());expect(a['reward_terms'])['not']['toBeNull'](),expect(a['reward_terms']['rewards'])['toEqual']([]),expect(a['reward_terms']['data_gaps'][0x0])['toContain'](REWARD),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());}),it('reward\x20lookup\x20throws\x20→\x20whole\x20lookup\x20degrades\x20to\x20one\x20gap\x20note,\x20never\x20thrown',async()=>{svcWithRewards(REWARD),sdkMocks['query_objects']['mockRejectedValue'](new Error('rpc\x20down'));const a=await handleServiceQuote(quoteInput());expect(a['reward_terms']['rewards'])['toEqual']([]),expect(a['reward_terms']['data_gaps'][0x0])['toContain']('rpc\x20down'),expect(a['total_pay']['balance'])['toBe'](LIST_TOTAL['toString']());});});function svcWithFund(a){sdkMocks['query_serviceContext']['mockResolvedValue']({'service':{'type_raw':'Service<0x2::wow::WOW>','sales':[{'name':FLEXIBLE,'price':{'balance':LIST_TOTAL['toString']()},'suspension':![]}],'compensation_fund':a}});}describe('service_quote\x20compensation_fund_coverage\x20(b6-11)',()=>{it('no\x20fund\x20→\x20covered:false\x20with\x20the\x20no-protection\x20disclosure\x20(never\x20blocked)',async()=>{const a=await handleServiceQuote(quoteInput());expect(a['compensation_fund_coverage'])['not']['toBeNull'](),expect(a['compensation_fund_coverage']['fund_balance'])['toBe']('0'),expect(a['compensation_fund_coverage']['required_for_this_basket'])['toBe']('2700000000'),expect(a['compensation_fund_coverage']['covered'])['toBe'](![]),expect(a['compensation_fund_coverage']['note'])['toContain']('WITHOUT\x20a\x20compensation\x20fund'),expect(a['compensation_fund_coverage']['note'])['toContain']('never\x20blocked');}),it('fund\x20at/over\x203x\x20the\x20basket\x20→\x20covered:true',async()=>{svcWithFund('2700000000');const a=await handleServiceQuote(quoteInput());expect(a['compensation_fund_coverage']['covered'])['toBe'](!![]),expect(a['compensation_fund_coverage']['note'])['toContain']('payable\x20from\x20the\x20pool');}),it('fund\x20short\x20→\x20covered:false\x20and\x20the\x20note\x20names\x20the\x20buy-time\x20block\x20+\x20error\x20code',async()=>{svcWithFund('100000000');const a=await handleServiceQuote(quoteInput());expect(a['compensation_fund_coverage']['covered'])['toBe'](![]),expect(a['compensation_fund_coverage']['note'])['toContain']('BLOCKED'),expect(a['compensation_fund_coverage']['note'])['toContain']('compensation_fund_below_order_ceiling'),expect(a['compensation_fund_coverage']['note'])['toContain']('compensation_fund_add');}),it('F-OF2-06:\x20max_coverable_order\x20names\x20the\x20storefront\x20price\x20cap\x20(fund/3)\x20in\x20every\x20fund\x20state',async()=>{const a=await handleServiceQuote(quoteInput());expect(a['compensation_fund_coverage']['max_coverable_order'])['toBe']('0'),svcWithFund('2700000000');const b=await handleServiceQuote(quoteInput());expect(b['compensation_fund_coverage']['max_coverable_order'])['toBe']('900000000'),expect(b['compensation_fund_coverage']['note'])['toContain']('ceiling'),svcWithFund('1000000000');const c=await handleServiceQuote(quoteInput());expect(c['compensation_fund_coverage']['max_coverable_order'])['toBe']('333333333'),expect(c['compensation_fund_coverage']['note'])['toContain']('orders\x20above');}),it('required\x20base\x20is\x20the\x20DISCOUNTED\x20total\x20(what\x20the\x20order\x20actually\x20pays)',async()=>{svcWithFund('2295000000');const a=await handleServiceQuote(quoteInput({'discount':'bk3t-promo15'}));expect(a['total_pay']['balance'])['toBe']('765000000'),expect(a['compensation_fund_coverage']['required_for_this_basket'])['toBe']('2295000000'),expect(a['compensation_fund_coverage']['covered'])['toBe'](!![]);});});
@@ -997,6 +997,7 @@ export declare const CallResponseErrorSchema: z.ZodObject<{
997
997
  submission_unknown: "submission_unknown";
998
998
  move_abort_unmapped: "move_abort_unmapped";
999
999
  missing_data: "missing_data";
1000
+ state_not_visible: "state_not_visible";
1000
1001
  }>>;
1001
1002
  retryable: z.ZodOptional<z.ZodBoolean>;
1002
1003
  recovery_hint: z.ZodOptional<z.ZodString>;
@@ -1576,6 +1577,12 @@ export declare const CallDataResultSchema: z.ZodObject<{
1576
1577
  export declare const CallNullResultSchema: z.ZodObject<{
1577
1578
  type: z.ZodLiteral<"null">;
1578
1579
  }, z.core.$strip>;
1580
+ export declare const CallReceiveAutoClaimedResultSchema: z.ZodObject<{
1581
+ type: z.ZodLiteral<"receive_auto_claimed">;
1582
+ receive_state: z.ZodLiteral<"auto_claimed">;
1583
+ receiver: z.ZodString;
1584
+ message: z.ZodString;
1585
+ }, z.core.$strip>;
1579
1586
  export declare const CallResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1580
1587
  type: z.ZodLiteral<"submission">;
1581
1588
  guard: z.ZodArray<z.ZodObject<{
@@ -1961,6 +1968,7 @@ export declare const CallResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1961
1968
  submission_unknown: "submission_unknown";
1962
1969
  move_abort_unmapped: "move_abort_unmapped";
1963
1970
  missing_data: "missing_data";
1971
+ state_not_visible: "state_not_visible";
1964
1972
  }>>;
1965
1973
  retryable: z.ZodOptional<z.ZodBoolean>;
1966
1974
  recovery_hint: z.ZodOptional<z.ZodString>;
@@ -2064,6 +2072,11 @@ export declare const CallResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2064
2072
  irreversible: z.ZodOptional<z.ZodBoolean>;
2065
2073
  }, z.core.$strict>;
2066
2074
  rule_id: z.ZodOptional<z.ZodString>;
2075
+ }, z.core.$strip>, z.ZodObject<{
2076
+ type: z.ZodLiteral<"receive_auto_claimed">;
2077
+ receive_state: z.ZodLiteral<"auto_claimed">;
2078
+ receiver: z.ZodString;
2079
+ message: z.ZodString;
2067
2080
  }, z.core.$strip>], "type">;
2068
2081
  export declare const ObjectsSchema: z.ZodPreprocess<z.ZodUnion<readonly [z.ZodObject<{
2069
2082
  op: z.ZodUnion<readonly [z.ZodLiteral<"add">, z.ZodLiteral<"set">]>;
@@ -2509,6 +2522,11 @@ export declare const CallOutputExecutedSchema: z.ZodObject<{
2509
2522
  }, z.core.$loose>>;
2510
2523
  }, z.core.$strip>, z.ZodObject<{
2511
2524
  type: z.ZodLiteral<"null">;
2525
+ }, z.core.$strip>, z.ZodObject<{
2526
+ type: z.ZodLiteral<"receive_auto_claimed">;
2527
+ receive_state: z.ZodLiteral<"auto_claimed">;
2528
+ receiver: z.ZodString;
2529
+ message: z.ZodString;
2512
2530
  }, z.core.$strip>], "type">;
2513
2531
  message: z.ZodOptional<z.ZodString>;
2514
2532
  semantic: z.ZodOptional<z.ZodObject<{
@@ -3418,6 +3436,7 @@ export declare const CallOutputFailedSchema: z.ZodObject<{
3418
3436
  submission_unknown: "submission_unknown";
3419
3437
  move_abort_unmapped: "move_abort_unmapped";
3420
3438
  missing_data: "missing_data";
3439
+ state_not_visible: "state_not_visible";
3421
3440
  }>>;
3422
3441
  retryable: z.ZodOptional<z.ZodBoolean>;
3423
3442
  recovery_hint: z.ZodOptional<z.ZodString>;
@@ -4234,6 +4253,11 @@ export declare const CallOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4234
4253
  }, z.core.$loose>>;
4235
4254
  }, z.core.$strip>, z.ZodObject<{
4236
4255
  type: z.ZodLiteral<"null">;
4256
+ }, z.core.$strip>, z.ZodObject<{
4257
+ type: z.ZodLiteral<"receive_auto_claimed">;
4258
+ receive_state: z.ZodLiteral<"auto_claimed">;
4259
+ receiver: z.ZodString;
4260
+ message: z.ZodString;
4237
4261
  }, z.core.$strip>], "type">;
4238
4262
  message: z.ZodOptional<z.ZodString>;
4239
4263
  semantic: z.ZodOptional<z.ZodObject<{
@@ -5141,6 +5165,7 @@ export declare const CallOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5141
5165
  submission_unknown: "submission_unknown";
5142
5166
  move_abort_unmapped: "move_abort_unmapped";
5143
5167
  missing_data: "missing_data";
5168
+ state_not_visible: "state_not_visible";
5144
5169
  }>>;
5145
5170
  retryable: z.ZodOptional<z.ZodBoolean>;
5146
5171
  recovery_hint: z.ZodOptional<z.ZodString>;