Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
"use strict" ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
exports . chainlistSupplement = chainlistSupplement ;
exports . etherscanV2Api = etherscanV2Api ;
const ethers _1 = require ( "ethers" ) ;
const config _1 = require ( "./config" ) ;
const addressIndex _1 = require ( "./addressIndex" ) ;
const chain138Explorer _1 = require ( "./chain138Explorer" ) ;
const iso20022LogDecode _1 = require ( "./iso20022LogDecode" ) ;
const participantSurfaceLogDecode _1 = require ( "./participantSurfaceLogDecode" ) ;
/** Etherscan V2-shaped envelope for tooling compatibility. */
function ok ( result , message = 'OK' ) {
return { status : '1' , message , result } ;
}
function err ( message , result = null ) {
return { status : '0' , message , result } ;
}
function normalizeAddress ( address ) {
try {
return ethers _1 . ethers . getAddress ( address ) ;
}
catch {
return ethers _1 . ethers . getAddress ( address . toLowerCase ( ) ) ;
}
}
function padTopicAddress ( address ) {
return ethers _1 . ethers . zeroPadValue ( normalizeAddress ( address ) , 32 ) ;
}
async function blockscoutTxList ( address , page , offset ) {
const base = config _1 . checkpointIndexerConfig . blockscoutApi . replace ( /\/$/ , '' ) ;
const url = ` ${ base } /addresses/ ${ normalizeAddress ( address ) } /transactions?page= ${ page } &offset= ${ offset } ` ;
const res = await fetch ( url ) ;
if ( ! res . ok )
throw new Error ( ` blockscout ${ res . status } ` ) ;
const body = ( await res . json ( ) ) ;
return ( body . items ? ? [ ] ) . map ( ( tx ) => ( {
blockNumber : String ( tx . block _number ? ? tx . blockNumber ? ? '' ) ,
timeStamp : tx . timestamp
? String ( Math . floor ( new Date ( String ( tx . timestamp ) ) . getTime ( ) / 1000 ) )
: '' ,
hash : tx . hash ,
from : tx . from ? . hash ? ? tx . from ,
to : tx . to ? . hash ? ? tx . to ,
value : String ( tx . value ? ? '0' ) ,
gas : String ( tx . fee ? . gas _used ? ? tx . gas _used ? ? '' ) ,
gasPrice : String ( tx . gas _price ? ? tx . gasPrice ? ? '0' ) ,
isError : tx . status === 'ok' || tx . status === 1 || tx . status === '0x1' ? '0' : '1' ,
txreceipt _status : tx . status === 'ok' || tx . status === 1 ? '1' : '0' ,
input : tx . raw _input ? ? tx . input ? ? '0x' ,
contractAddress : '' ,
cumulativeGasUsed : '' ,
confirmations : String ( tx . confirmations ? ? '' ) ,
} ) ) ;
}
async function etherscanV2GetLogs ( params , apiKey ) {
const q = new URLSearchParams ( params ) ;
q . set ( 'chainid' , '1' ) ;
q . set ( 'module' , 'logs' ) ;
q . set ( 'action' , 'getLogs' ) ;
if ( apiKey )
q . set ( 'apikey' , apiKey ) ;
const url = ` https://api.etherscan.io/v2/api? ${ q . toString ( ) } ` ;
const res = await fetch ( url ) ;
return res . json ( ) ;
}
function chainlistSupplement ( _req , res ) {
const registry = config _1 . checkpointIndexerConfig . addressActivityRegistry || null ;
res . json ( {
comments : 'Supplemental chainlist for networks absent from official Etherscan V2 chainlist. Not maintained by Etherscan.' ,
totalcount : 2 ,
result : [
{
chainname : 'Defi Oracle Meta Mainnet' ,
chainid : '138' ,
blockexplorer : 'https://explorer.d-bis.org/' ,
apiurl : ` ${ publicBase ( _req ) } /v2/api?chainid=138 ` ,
status : 1 ,
comment : 'Blockscout native + project attestation shim' ,
} ,
{
chainname : 'Ethereum Mainnet (Chain 138 attestation layer)' ,
chainid : '1' ,
attestationLayer : true ,
blockexplorer : 'https://etherscan.io/' ,
apiurl : ` ${ publicBase ( _req ) } /v2/api?chainid=1&module=chain138mirror ` ,
status : 1 ,
comment : 'Query mirror/registry logs via chain138mirror module on this shim (not native Etherscan V2 module=account)' ,
contracts : {
transactionMirror : config _1 . checkpointIndexerConfig . legacyMirror ,
addressActivityRegistry : registry ,
addressActivityRegistryV2 : config _1 . checkpointIndexerConfig . addressActivityRegistryV2 || null ,
iso20022IntakeGateway : config _1 . checkpointIndexerConfig . iso20022IntakeGateway || null ,
checkpointHub : config _1 . checkpointIndexerConfig . checkpointProxy || null ,
} ,
} ,
] ,
} ) ;
}
function publicBase ( req ) {
const proto = req . headers [ 'x-forwarded-proto' ] || req . protocol ;
const host = req . headers [ 'x-forwarded-host' ] || req . headers . host || ` 127.0.0.1: ${ config _1 . checkpointIndexerConfig . port } ` ;
return ` ${ proto } :// ${ host } ` ;
}
async function etherscanV2Api ( req , res ) {
const q = req . query ;
const chainid = String ( q . chainid ? ? '' ) ;
const module = String ( q . module ? ? '' ) ;
const action = String ( q . action ? ? '' ) ;
const apiKey = String ( q . apikey ? ? process . env . ETHERSCAN _API _KEY ? ? '' ) ;
if ( ! chainid ) {
return res . json ( err ( 'Missing or unsupported chainid parameter (required for v2 api), please see chainlist-supplement for Chain 138' ) ) ;
}
try {
if ( chainid === '138' ) {
return res . json ( await handleChain138 ( module , action , q ) ) ;
}
if ( chainid === '1' && module === 'chain138mirror' ) {
return res . json ( await handleMainnetAttestation ( action , q , apiKey ) ) ;
}
if ( chainid === '1' && module === 'proxy' ) {
return res . json ( err ( 'Use official https://api.etherscan.io/v2/api for chainid=1 proxy module' ) ) ;
}
return res . json ( err ( ` Chain ${ chainid } is not served by this shim. Chain 138 native: chainid=138. Chain 138 on mainnet attestation: chainid=1&module=chain138mirror ` ) ) ;
}
catch ( e ) {
return res . json ( err ( String ( e ) ) ) ;
}
}
async function handleChain138 ( module , action , q ) {
const address = String ( q . address ? ? '' ) ;
if ( module === 'account' && action === 'balance' ) {
if ( ! /^0x[a-fA-F0-9]{40}$/ . test ( address ) )
return err ( 'Invalid address' ) ;
const provider = new ethers _1 . ethers . JsonRpcProvider ( config _1 . checkpointIndexerConfig . chain138Rpc ) ;
const bal = await provider . getBalance ( normalizeAddress ( address ) ) ;
return ok ( bal . toString ( ) ) ;
}
if ( module === 'account' && action === 'txlist' ) {
if ( ! /^0x[a-fA-F0-9]{40}$/ . test ( address ) )
return err ( 'Invalid address' ) ;
const page = parseInt ( String ( q . page ? ? '1' ) , 10 ) || 1 ;
const offset = Math . min ( parseInt ( String ( q . offset ? ? '10' ) , 10 ) || 10 , 100 ) ;
const items = await blockscoutTxList ( normalizeAddress ( address ) , page , offset ) ;
return ok ( items ) ;
}
if ( module === 'chain138' && action === 'attestation' ) {
const txHash = String ( q . txhash ? ? q . txHash ? ? '' ) ;
if ( ! /^0x[a-fA-F0-9]{64}$/ . test ( txHash ) )
return err ( 'Invalid txhash' ) ;
const base = publicBaseFromQuery ( q ) ;
const r = await fetch ( ` ${ base } /v1/tx/ ${ txHash } /attestation ` ) ;
if ( ! r . ok )
return err ( 'attestation not found' ) ;
return ok ( await r . json ( ) ) ;
}
if ( module === 'chain138' && action === 'participantactivity' ) {
if ( ! /^0x[a-fA-F0-9]{40}$/ . test ( address ) )
return err ( 'Invalid address' ) ;
const normalized = normalizeAddress ( address ) ;
const index = ( 0 , addressIndex _1 . buildAddressIndex ) ( config _1 . checkpointIndexerConfig . batchPayloadDir ) ;
const { total , items } = ( 0 , addressIndex _1 . getAddressTransactions ) ( index , normalized , Math . min ( parseInt ( String ( q . offset ? ? '50' ) , 10 ) || 50 , 200 ) , parseInt ( String ( q . page ? ? '0' ) , 10 ) || 0 ) ;
const summary = ( 0 , addressIndex _1 . summarizeAddressActivity ) ( index . byAddress [ normalized . toLowerCase ( ) ] ? ? [ ] ) ;
2026-06-08 08:13:59 -07:00
const explorerBase = ( 0 , chain138Explorer _1 . chain138ExplorerBase ) ( ) ;
const enrichedItems = items . map ( ( row ) => ( {
... row ,
chain138ExplorerUrl : ( 0 , chain138Explorer _1 . chain138ExplorerTxUrl ) ( row . txHash , explorerBase ) ,
roleLabel : row . role === 'from' ? 'debited' : 'credited' ,
} ) ) ;
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
const onChainHint = total === 0 && config _1 . checkpointIndexerConfig . addressActivityRegistry
? {
registry : config _1 . checkpointIndexerConfig . addressActivityRegistry ,
query : 'GET /v2/api?chainid=1&module=chain138mirror&action=participantlogs&address=' +
normalized ,
}
: null ;
2026-06-08 08:13:59 -07:00
return ok ( {
total ,
summary ,
items : enrichedItems ,
onChainHint ,
chain138Explorer : { base : explorerBase , txUrlTemplate : ` ${ explorerBase } /tx/{txHash} ` } ,
} ) ;
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
}
if ( module === 'proxy' && action === 'eth_blockNumber' ) {
const provider = new ethers _1 . ethers . JsonRpcProvider ( config _1 . checkpointIndexerConfig . chain138Rpc ) ;
const block = await provider . getBlockNumber ( ) ;
return ok ( ` 0x ${ block . toString ( 16 ) } ` ) ;
}
return err ( ` Unsupported module/action for chainid=138: ${ module } / ${ action } ` ) ;
}
function publicBaseFromQuery ( q ) {
const override = String ( q . indexerBase ? ? process . env . CHECKPOINT _PAYLOAD _PUBLIC _URL ? ? '' ) ;
if ( override . startsWith ( 'http' ) )
return override . replace ( /\/v1\/payload\/?$/ , '' ) . replace ( /\/$/ , '' ) ;
return ` http://127.0.0.1: ${ config _1 . checkpointIndexerConfig . port } ` ;
}
async function handleMainnetAttestation ( action , q , apiKey ) {
const registry = config _1 . checkpointIndexerConfig . addressActivityRegistry ;
const mirror = config _1 . checkpointIndexerConfig . legacyMirror ;
const address = String ( q . address ? ? '' ) ;
if ( action === 'contracts' ) {
const explorerBase = ( 0 , chain138Explorer _1 . chain138ExplorerBase ) ( ) ;
return ok ( {
transactionMirror : mirror ,
addressActivityRegistry : registry || null ,
checkpointHub : config _1 . checkpointIndexerConfig . checkpointProxy || null ,
chain138Explorer : {
base : explorerBase ,
txUrlTemplate : ` ${ explorerBase } /tx/{txHash} ` ,
} ,
eventTopics : {
TransactionMirrored : '0xc25ce5062c7e42c68fa21fe088d21e609cc0c61b8bec3180681363bb5cf02a9e' ,
ParticipantCredited : '0x853ebad0824f583553bcb4360a0df947d39654e86aba8d7c0625499cbf09f0d5' ,
ParticipantDebited : '0xf122cad7c8ada37ddd6b6ddca0982b9f7be689cde15eedfd767cc207fa7dc2c8' ,
} ,
} ) ;
}
if ( action === 'participantlogs' ) {
if ( ! registry && ! config _1 . checkpointIndexerConfig . addressActivityRegistryV2 ) {
return err ( 'ADDRESS_ACTIVITY_REGISTRY_MAINNET or V2 not configured' ) ;
}
if ( ! /^0x[a-fA-F0-9]{40}$/ . test ( address ) )
return err ( 'Invalid address' ) ;
if ( ! apiKey )
return err ( 'ETHERSCAN_API_KEY required for mainnet log proxy' ) ;
const topic = padTopicAddress ( address ) ;
const params = new URLSearchParams ( {
fromBlock : String ( q . fromBlock ? ? '0' ) ,
toBlock : String ( q . toBlock ? ? 'latest' ) ,
} ) ;
let credited = { status : '0' , message : 'No records' , result : [ ] } ;
let debited = { status : '0' , message : 'No records' , result : [ ] } ;
if ( registry ) {
const regParams = new URLSearchParams ( [ ... params . entries ( ) , [ 'address' , registry ] ] ) ;
credited = await etherscanV2GetLogs ( new URLSearchParams ( [
... regParams . entries ( ) ,
[ 'topic0' , '0x853ebad0824f583553bcb4360a0df947d39654e86aba8d7c0625499cbf09f0d5' ] ,
[ 'topic2' , topic ] ,
] ) , apiKey ) ;
debited = await etherscanV2GetLogs ( new URLSearchParams ( [
... regParams . entries ( ) ,
[ 'topic0' , '0xf122cad7c8ada37ddd6b6ddca0982b9f7be689cde15eedfd767cc207fa7dc2c8' ] ,
[ 'topic3' , topic ] ,
] ) , apiKey ) ;
}
let surfaceNotify = null ;
if ( config _1 . checkpointIndexerConfig . participantSurface ) {
const surfaceRaw = await etherscanV2GetLogs ( new URLSearchParams ( [
... params . entries ( ) ,
[ 'address' , config _1 . checkpointIndexerConfig . participantSurface ] ,
[ 'topic0' , participantSurfaceLogDecode _1 . CHAIN138 _ACTIVITY _NOTIFIED _TOPIC0 ] ,
[ 'topic1' , topic ] ,
] ) , apiKey ) ;
const surfaceEnv = surfaceRaw ;
surfaceNotify = {
status : surfaceEnv . status ,
result : surfaceEnv . result ? ? [ ] ,
decoded : ( 0 , participantSurfaceLogDecode _1 . decodeChain138ActivityNotifiedLogs ) ( surfaceEnv , ( 0 , chain138Explorer _1 . chain138ExplorerBase ) ( ) ) ,
} ;
}
2026-06-08 08:13:59 -07:00
const explorerBase = ( 0 , chain138Explorer _1 . chain138ExplorerBase ) ( ) ;
const index = ( 0 , addressIndex _1 . buildAddressIndex ) ( config _1 . checkpointIndexerConfig . batchPayloadDir ) ;
const normalized = normalizeAddress ( address ) ;
const { total : batchTotal , items : batchItems } = ( 0 , addressIndex _1 . getAddressTransactions ) ( index , normalized , 200 , 0 ) ;
const batchIndexedActivity = batchItems . map ( ( row ) => ( {
... row ,
chain138ExplorerUrl : ( 0 , chain138Explorer _1 . chain138ExplorerTxUrl ) ( row . txHash , explorerBase ) ,
roleLabel : row . role === 'from' ? 'debited' : 'credited' ,
} ) ) ;
const debtorTxHashes = [
... new Set ( batchItems . filter ( ( r ) => r . role === 'from' ) . map ( ( r ) => r . txHash . toLowerCase ( ) ) ) ,
] ;
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
let isoV2 = null ;
if ( config _1 . checkpointIndexerConfig . addressActivityRegistryV2 ) {
const v2raw = await etherscanV2GetLogs ( new URLSearchParams ( [
... params . entries ( ) ,
[ 'address' , config _1 . checkpointIndexerConfig . addressActivityRegistryV2 ] ,
[ 'topic0' , iso20022LogDecode _1 . PAYMENT _ATTESTED _TOPIC0 ] ,
[ 'topic3' , topic ] ,
] ) , apiKey ) ;
const v2env = v2raw ;
2026-06-08 08:13:59 -07:00
const decodedCreditor = ( 0 , iso20022LogDecode _1 . decodePaymentAttestedLogs ) ( v2env , explorerBase ) ;
const decodedDebtor = [ ] ;
for ( const txHash of debtorTxHashes ) {
const byTx = await etherscanV2GetLogs ( new URLSearchParams ( [
... params . entries ( ) ,
[ 'address' , config _1 . checkpointIndexerConfig . addressActivityRegistryV2 ] ,
[ 'topic0' , iso20022LogDecode _1 . PAYMENT _ATTESTED _TOPIC0 ] ,
[ 'topic1' , txHash ] ,
] ) , apiKey ) ;
decodedDebtor . push ( ... ( 0 , iso20022LogDecode _1 . decodePaymentAttestedLogs ) ( byTx , explorerBase ) . filter ( ( d ) => d . debtor . toLowerCase ( ) === normalized . toLowerCase ( ) ) ) ;
}
const merged = new Map ( ) ;
for ( const row of [ ... decodedCreditor , ... decodedDebtor ] ) {
merged . set ( ` ${ row . chain138TxHash } : ${ row . mainnetTxHash } ` , row ) ;
}
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
isoV2 = {
status : v2env . status ,
result : v2env . result ? ? [ ] ,
2026-06-08 08:13:59 -07:00
decoded : [ ... merged . values ( ) ] ,
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
} ;
}
return ok ( {
2026-06-08 08:13:59 -07:00
participant : normalized ,
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
registry : registry || null ,
registryV2 : config _1 . checkpointIndexerConfig . addressActivityRegistryV2 || null ,
participantSurface : config _1 . checkpointIndexerConfig . participantSurface || null ,
credited : ( 0 , chain138Explorer _1 . enrichRegistryLogsEnvelope ) ( credited ) ,
debited : ( 0 , chain138Explorer _1 . enrichRegistryLogsEnvelope ) ( debited ) ,
surfaceNotifications : surfaceNotify ,
iso20022V2 : isoV2 ,
2026-06-08 08:13:59 -07:00
batchIndexedActivity : {
total : batchTotal ,
items : batchIndexedActivity ,
} ,
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
chain138Explorer : {
2026-06-08 08:13:59 -07:00
base : explorerBase ,
txUrlTemplate : ` ${ explorerBase } /tx/{txHash} ` ,
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
} ,
topicIndex : {
ParticipantCredited : { chain138TxHash : 'topic1' , participant : 'topic2' , counterparty : 'topic3' } ,
ParticipantDebited : { chain138TxHash : 'topic1' , counterparty : 'topic2' , participant : 'topic3' } ,
2026-06-08 08:13:59 -07:00
PaymentAttested : { chain138TxHash : 'topic1' , instructionId : 'topic2' , creditor : 'topic3' , debtor : 'data' } ,
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
Chain138ActivityNotified : {
participant : 'topic1' ,
chain138TxHash : 'topic2' ,
instructionId : 'topic3' ,
} ,
} ,
etherscanVisibility : {
2026-06-08 08:13:59 -07:00
transactionsTab : 'Incoming 0 ETH txs to participant (CHECKPOINT_SURFACE_TOPLEVEL_ZERO_ETH=1, default on) — calldata chain138Attestation(bytes32,uint8,uint64)' ,
internalTxnsTab : 'Chain138ParticipantSurface wallet touch per sender and receiver' ,
eventsOnSurfaceContract : 'surfaceNotifications.decoded[] — filter topic1=participant on surface contract' ,
registryV1Logs : 'credited/debited.decoded[] — ParticipantCredited + ParticipantDebited' ,
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
} ,
2026-06-08 08:13:59 -07:00
note : 'Each Chain 138 payment surfaces twice on mainnet: debited (from) + credited (to). batchIndexedActivity.items[] lists both roles with chain138TxHash. Full pacs.008 XML in batch payloads.' ,
Add mainnet checkpoint stack: ISO attestation, participant Etherscan surface, and services.
Ship AddressActivityRegistry V1/V2, ISO20022IntakeGateway, Chain138ParticipantSurface,
checkpoint hub contracts, checkpoint-core package, aggregator/indexer/sdk services,
relay profile guards, M00 diamond bridge facet, and OMNL compliance contracts.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 00:30:45 -07:00
} ) ;
}
if ( action === 'mirrorlogs' ) {
if ( ! /^0x[a-fA-F0-9]{64}$/ . test ( String ( q . txhash ? ? '' ) ) )
return err ( 'Invalid txhash' ) ;
if ( ! apiKey )
return err ( 'ETHERSCAN_API_KEY required' ) ;
const txHash = String ( q . txhash ) ;
const params = new URLSearchParams ( {
address : mirror ,
fromBlock : String ( q . fromBlock ? ? '0' ) ,
toBlock : String ( q . toBlock ? ? 'latest' ) ,
topic0 : '0xc25ce5062c7e42c68fa21fe088d21e609cc0c61b8bec3180681363bb5cf02a9e' ,
topic1 : txHash ,
} ) ;
const logs = await etherscanV2GetLogs ( params , apiKey ) ;
return ok ( logs ) ;
}
return err ( ` Unsupported chain138mirror action: ${ action } ` ) ;
}