@jdr377/mapapp-agent-connector 0.0.0-stage → 0.1.0-pre.1
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.
- package/README.md +177 -2
- package/bun.lock +339 -0
- package/dist/chunk-0033d0wt.js +2 -0
- package/dist/chunk-ajs19nj9.js +3 -0
- package/dist/chunk-btwmey1h.js +3 -0
- package/dist/chunk-c74qq5ek.js +2 -0
- package/dist/chunk-e6y2yzbj.js +3 -0
- package/dist/chunk-k75c97va.js +17 -0
- package/dist/chunk-r4m45n3d.js +4 -0
- package/dist/chunk-wy5sgkmh.js +3 -0
- package/dist/participant-mcp-server.js +12 -0
- package/distribution.json +243 -0
- package/package.json +44 -4
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{BSOCIAL_BASKET,ORDINALS_BASKET}from"@1sat/actions";import{Beef}from"@bsv/sdk";import{executeTrackedAction}from"@1sat/actions";import{Transaction,Validation}from"@bsv/sdk";class NativeActionPreDispatchError extends Error{code="native_action_pre_dispatch_rejected";constructor(message,options){super(message,options);this.name="NativeActionPreDispatchError"}}class NativeActionNoTransactionError extends Error{code;constructor(code,message,cause){super(message,{cause});this.name="NativeActionNoTransactionError";this.code=code}}var MAX_CLIENT_ATOMIC_BEEF_BYTES=2*1024*1024;function normalizePaidPostActionOutcome(provider,value){const candidate=isRecord(value)?value:{};const txid=normalizeTxid(candidate.txid);const atomicBeef=normalizeEvidenceBytes(candidate.tx);const review=reviewActionEvidence(value);if(atomicBeef){let atomicSubjectTxid=null;let anomaly=null;try{atomicSubjectTxid=Beef.fromBinary(atomicBeef).atomicTxid??null;if(!atomicSubjectTxid)anomaly="invalid_atomic_beef"}catch{anomaly="invalid_atomic_beef"}const declared=txid??atomicSubjectTxid;if(!declared)return{kind:"wallet_outcome_unknown",provider,message:"Wallet returned transaction bytes without a recoverable AtomicBEEF subject."};if(!txid&&atomicSubjectTxid)anomaly="missing_declared_txid";else if(txid&&atomicSubjectTxid&&txid!==atomicSubjectTxid)anomaly="subject_txid_mismatch";return{kind:"creation_evidence",provider,txid:declared,atomicSubjectTxid,atomicBeef,anomaly,review}}if(txid)return{kind:"awaiting_evidence",provider,txid};if(provider==="native"&&nativeDefiniteRejectionError(value)){return{kind:"wallet_rejected",provider,message:errorMessage(value)}}if(provider==="native"&&candidate.ok===false&&typeof candidate.code==="string"&&["storage_parity_unverified","backup_unconfigured","backup_degraded_after_relay","backup_flush_failed"].includes(candidate.code)){return{kind:"wallet_rejected",provider,message:errorMessage(candidate.message)}}return review?{kind:"wallet_outcome_unknown",provider,message:errorMessage(value),review}:{kind:"wallet_outcome_unknown",provider,message:errorMessage(value)}}async function executePaidPostAction(args){const agentProfile=args.agentProofProfile;const qualified=args.provider==="agent-wallet-node"?agentProfile?.transport==="direct_wallet_node"&&agentProfile.authority==="full_root_authority"&&agentProfile.connectionReceipt==="mapapp-705.21"&&["controlled_fixture","operator_authorized_proof"].includes(agentProfile.qualification)||agentProfile?.qualification==="participant_release"&&(agentProfile.transport==="direct_wallet_node"&&agentProfile.authority==="full_root_authority"&&agentProfile.connectionReceipt==="mapapp-705.31"||agentProfile.transport==="brc100_http"&&agentProfile.authority==="provider"&&agentProfile.connectionReceipt==="mapapp-705.32"):args.providerAttested||args.u8RuntimeParityEnabled;if(!qualified){return{kind:"provider_unattested",intentId:null,retryAllowed:false,message:`The ${args.provider} wallet interface has not passed runtime provenance attestation.`}}const intentId=args.intentId??newIntentId();let intent;try{intent=await args.client.createIntent(args.clientIntentId,intentId,args.actionKind??"post",args.actionTarget)}catch(cause){return{kind:"intent_creation_rejected",intentId,retryAllowed:false,code:isRecord(cause)&&typeof cause.code==="string"?cause.code:"intent_creation_rejected",message:errorMessage(cause)}}try{await args.localIntentStore.persistReference({...intent,clientIntentId:args.clientIntentId,evidenceFormat:args.evidenceFormat??"mapapp_post_v1"},args.draft)}catch(cause){try{await args.client.terminateIntent(intent.intentId,"local_intent_persistence_failed")}catch{}return{kind:"local_intent_persistence_failed",intentId:intent.intentId,retryAllowed:true,message:errorMessage(cause)}}if(args.beforeClaim){try{await args.beforeClaim(intent.intentId)}catch(cause){await args.client.terminateIntent(intent.intentId,"thumbnail_stage_failed").catch(()=>{return});return{kind:"thumbnail_stage_failed",intentId:intent.intentId,retryAllowed:true,message:`The thumbnail could not be retained before wallet approval: ${errorMessage(cause)}`}}}const claim=await args.client.claimInvocation(intent.intentId,args.tabId);if(!claim.claimed){return{kind:"invocation_claim_rejected",intentId:intent.intentId,retryAllowed:false,message:"This transaction intent was already claimed for wallet invocation."}}let returned;try{returned=await args.invoke({intentId:intent.intentId,intentNonce:intent.nonce,outputTags:[intent.correlationTag],labels:[...args.actionLabelEnabled?["mapapp paid post"]:[],...args.provider!=="external-cwi"?[`mapapp correlation ${intent.correlationTag}`]:[]],...args.provider==="native"&&args.evidenceFormat==="mapapp_direct_bsv_v1"?{retainEvidence:async(txid,atomicBeef)=>{if(!args.localIntentStore.persistEvidence)throw new Error("Encrypted exact-evidence retention is unavailable.");await args.localIntentStore.persistEvidence(intent.intentId,txid,atomicBeef)}}:{}})}catch(cause){returned=cause}const outcome=normalizePaidPostActionOutcome(args.provider,returned);if(outcome.kind==="wallet_outcome_unknown"&&outcome.review){console.warn("[mapapp-wallet] wallet_review_required",{intentId:intent.intentId,actionKind:args.actionKind??"post",provider:args.provider,code:outcome.review.code,reviewActionResults:outcome.review.reviewActionResultCount,sendWithResults:outcome.review.sendWithResultCount,hasTxid:false,hasAtomicBeef:false})}try{if(outcome.kind==="creation_evidence"){if(args.provider!=="external-cwi"&&!outcome.anomaly&&args.localIntentStore.persistEvidence){await args.localIntentStore.persistEvidence(intent.intentId,outcome.txid,outcome.atomicBeef)}const submitted=await args.client.submitEvidence(intent.intentId,outcome.txid,outcome.atomicBeef);if(!isAcceptedIntakeStatus(submitted.status)){return{kind:"intake_handoff_failed",intentId:intent.intentId,retryAllowed:false,message:submitted.status==="quarantined"?"MapApp quarantined the wallet transaction evidence. Do not submit the action again.":"MapApp did not accept the wallet transaction evidence. Do not submit the action again.",walletOutcome:outcome}}return{...outcome,intentId:intent.intentId,retryAllowed:false,intakeStatus:submitted.status}}const state=outcome.kind==="awaiting_evidence"?"awaiting_evidence":outcome.kind==="wallet_rejected"?"wallet_rejected":"wallet_outcome_unknown";await args.client.recordOutcome(intent.intentId,state,outcome.kind==="awaiting_evidence"?outcome.txid:undefined);return{...outcome,intentId:intent.intentId,retryAllowed:false}}catch(cause){return{kind:"intake_handoff_failed",intentId:intent.intentId,retryAllowed:false,message:errorMessage(cause),walletOutcome:outcome}}}async function recoverPaidPostEvidence(args){const evidenceFormat=args.evidenceFormat??"mapapp_post_v1";let result;try{result=await args.wallet.listOutputs({basket:evidenceFormat==="mapapp_post_v1"?ORDINALS_BASKET:BSOCIAL_BASKET,tags:[args.correlationTag],tagQueryMode:"all",include:"entire transactions",includeTags:true,limit:2,offset:0})}catch(cause){return unresolved("permission_or_provider_error",compactProviderError(cause))}if(!isRecord(result)||!Array.isArray(result.outputs)||typeof result.totalOutputs!=="number"){return unresolved("unsupported_list_outputs_response","Wallet recovery returned an unsupported listOutputs response.")}if(result.totalOutputs!==1||result.outputs.length!==1){return unresolved("no_unique_output","Wallet recovery did not return exactly one tagged root output.")}const output=result.outputs[0];if(!isRecord(output)){return unresolved("unsupported_list_outputs_response","Wallet recovery returned an unsupported output record.")}if(output.spendable!==true)return unresolved("output_spent_or_untracked","The tagged wallet output is spent or no longer tracked.");if(!result.BEEF)return unresolved("missing_aggregate_beef","Wallet recovery returned no aggregate transaction evidence.");const match=typeof output.outpoint==="string"?/^([0-9a-fA-F]{64})\.(\d+)$/.exec(output.outpoint):null;if(!match)return unresolved("invalid_outpoint","Wallet recovery returned a malformed output reference.");if(evidenceFormat!=="mapapp_post_v1"&&(Number(match[2])!==0||output.satoshis!==0)){return unresolved("invalid_root_output","Post v2 recovery requires the zero-satoshi social root at vout 0.")}const txid=match[1].toLowerCase();try{const aggregate=Beef.fromBinary(result.BEEF);const subject=aggregate.findTxid(txid);if(!subject||subject.isTxidOnly||!subject.rawTxUint8Array){return unresolved("subject_transaction_missing","Aggregate evidence does not contain the recovered root transaction.")}const rootSatoshis=subject.tx?.outputs[0]?.satoshis;if(evidenceFormat!=="mapapp_post_v1"&&(rootSatoshis===undefined||Number(rootSatoshis)!==0)){return unresolved("invalid_root_output","Aggregate evidence does not contain the zero-satoshi social root at vout 0.")}return{kind:"recovered",txid,atomicBeef:aggregate.toUint8ArrayAtomic(txid)}}catch{return unresolved("invalid_aggregate_beef","Wallet recovery returned invalid aggregate transaction evidence.")}}function unresolved(reason,message){return{kind:"unresolved",reason,message}}function compactProviderError(value){const detail=errorMessage(value).replace(/\s+/g," ").trim().slice(0,160);return detail?`Wallet recovery was denied or unsupported: ${detail}`:"Wallet recovery was denied or is unsupported by this provider."}function reviewActionEvidence(value){if(!isRecord(value)||value.name!=="WERR_REVIEW_ACTIONS"||!Array.isArray(value.reviewActionResults)||!Array.isArray(value.sendWithResults))return null;return{name:"WERR_REVIEW_ACTIONS",code:typeof value.code==="number"?value.code:null,reviewActionResultCount:Math.min(value.reviewActionResults.length,1000),sendWithResultCount:Math.min(value.sendWithResults.length,1000)}}function isAcceptedIntakeStatus(status){return status==="staged"||status==="bound"||status==="idempotent"||status==="already_bound"}function normalizeEvidenceBytes(value){if(value instanceof Uint8Array){if(value.byteLength===0||value.byteLength>MAX_CLIENT_ATOMIC_BEEF_BYTES)return null;return value}if(!Array.isArray(value)||value.length===0||value.length>MAX_CLIENT_ATOMIC_BEEF_BYTES)return null;for(let index=0;index<value.length;index+=1){if(!Object.prototype.hasOwnProperty.call(value,index))return null;const byte=value[index];if(!Number.isInteger(byte)||byte<0||byte>255)return null}return new Uint8Array(value)}function normalizeTxid(value){return typeof value==="string"&&/^[0-9a-fA-F]{64}$/.test(value)?value.toLowerCase():null}function errorMessage(value){const raw=value instanceof Error&&value.message?value.message:typeof value==="string"&&value.trim()?value:isRecord(value)&&typeof value.message==="string"&&value.message?value.message:isRecord(value)&&typeof value.error==="string"&&value.error?value.error:"";const sanitized=raw.replace(/<[^>]*>/g," ").replace(/\b(?:seed|mnemonic|private[-_ ]?key|password|secret|token)\s*[:=]\s*\S+/gi,"[redacted]").replace(new RegExp(`[${String.fromCharCode(0)}-${String.fromCharCode(31)}${String.fromCharCode(127)}]+`,"g")," ").replace(/\s+/g," ").trim().slice(0,240);if(sanitized)return sanitized;return"Wallet invocation completed without structured transaction evidence."}function nativeDefiniteRejectionError(value){let current=value;for(let depth=0;depth<3;depth+=1){if(current instanceof NativeActionPreDispatchError||current instanceof NativeActionNoTransactionError)return current;current=current instanceof Error?current.cause:null}return null}function isRecord(value){return typeof value==="object"&&value!==null}function newIntentId(){if(typeof globalThis.crypto?.randomUUID==="function")return globalThis.crypto.randomUUID();throw new Error("Secure intent identifiers are unavailable in this runtime.")}
|
|
3
|
+
export{MAX_CLIENT_ATOMIC_BEEF_BYTES,normalizePaidPostActionOutcome,executePaidPostAction,recoverPaidPostEvidence};
|