Merge remote-tracking branch 'origin/main' into blockchain-watcher/multi-instance
This commit is contained in:
commit
5737b73949
|
@ -37,38 +37,89 @@ By default, jobs are read from `metadata-repo/jobs/jobs.json`.
|
|||
Example:
|
||||
|
||||
```
|
||||
{ "jobs": [
|
||||
{
|
||||
"id": "poll-log-message-published-ethereum",
|
||||
"chain": "ethereum",
|
||||
"source": {
|
||||
"action": "PollEvmLogs",
|
||||
"config": {
|
||||
"fromBlock": "10012499",
|
||||
"blockBatchSize": 100,
|
||||
"commitment": "latest",
|
||||
"interval": 15000,
|
||||
"addresses": ["0x706abc4E45D419950511e474C7B9Ed348A4a716c"],
|
||||
"chain": "ethereum",
|
||||
"topics": []
|
||||
}
|
||||
},
|
||||
"handlers": [
|
||||
{
|
||||
"action": "HandleEvmLogs",
|
||||
"target": "sns",
|
||||
"mapper": "evmLogMessagePublishedMapper",
|
||||
{
|
||||
"jobs": [
|
||||
{
|
||||
"id": "poll-log-message-published-ethereum",
|
||||
"chain": "ethereum",
|
||||
"source": {
|
||||
"action": "PollEvmLogs",
|
||||
"config": {
|
||||
"abi": "event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel)",
|
||||
"filter": {
|
||||
"addresses": ["0x706abc4E45D419950511e474C7B9Ed348A4a716c"],
|
||||
"topics": ["0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2"]
|
||||
"fromBlock": "10012499",
|
||||
"blockBatchSize": 100,
|
||||
"commitment": "latest",
|
||||
"interval": 15000,
|
||||
"addresses": ["0x706abc4E45D419950511e474C7B9Ed348A4a716c"],
|
||||
"chain": "ethereum",
|
||||
"topics": []
|
||||
}
|
||||
},
|
||||
"handlers": [
|
||||
{
|
||||
"action": "HandleEvmLogs",
|
||||
"target": "sns",
|
||||
"mapper": "evmLogMessagePublishedMapper",
|
||||
"config": {
|
||||
"abi": "event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel)",
|
||||
"filter": {
|
||||
"addresses": ["0x706abc4E45D419950511e474C7B9Ed348A4a716c"],
|
||||
"topics": ["0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"action": "HandleEvmLogs",
|
||||
"target": "sns",
|
||||
"mapper": "evmTransferRedeemedMapper",
|
||||
"config": {
|
||||
"abi": "event TransferRedeemed(uint16 indexed emitterChainId, bytes32 indexed emitterAddress, uint64 indexed sequence)",
|
||||
"filter": {
|
||||
"addresses": ["0x3ee18b2214aff97000d974cf647e7c347e8fa585"],
|
||||
"topics": ["0xcaf280c8cfeba144da67230d9b009c8f868a75bac9a528fa0474be1ba317c169"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"action": "HandleEvmLogs",
|
||||
"target": "sns",
|
||||
"mapper": "evmStandardRelayDelivered",
|
||||
"config": {
|
||||
"abi": "event Delivery(address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)",
|
||||
"filter": {
|
||||
"addresses": ["0x27428dd2d3dd32a4d7f7c497eaaa23130d894911"],
|
||||
"topics": ["0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "poll-transfer-redeemed-solana",
|
||||
"chain": "solana",
|
||||
"source": {
|
||||
"action": "PollSolanaTransactions",
|
||||
"config": {
|
||||
"slotBatchSize": 1000,
|
||||
"commitment": "finalized",
|
||||
"interval": 1500,
|
||||
"signaturesLimit": 200,
|
||||
"programId": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb",
|
||||
"chain": "solana"
|
||||
}
|
||||
},
|
||||
"handlers": [
|
||||
{
|
||||
"action": "HandleSolanaTransactions",
|
||||
"target": "sns",
|
||||
"mapper": "solanaTransferRedeemedMapper",
|
||||
"config": {
|
||||
"programId": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ info:
|
|||
Platform service that allows to extract, transform and load data from different blockchains platforms.
|
||||
servers:
|
||||
staging-testnet:
|
||||
url: arn:aws:sns:us-east-2:581679387567:notification-chain-events-dev-testnet.fifo
|
||||
url: notification-chain-events-dev-testnet.fifo
|
||||
protocol: sns
|
||||
defaultContentType: application/json
|
||||
channels:
|
||||
|
@ -34,6 +34,44 @@ components:
|
|||
contentType: application/json
|
||||
payload:
|
||||
$ref: "#/components/schemas/transferRedeemed"
|
||||
examples:
|
||||
- name: TransferRedeemed in Solana from Ethereum
|
||||
payload:
|
||||
name: "transfer-redeemed"
|
||||
address: wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb
|
||||
chainId: 1
|
||||
txHash: 3FySmshUgVCM2N158oNYbeTfZt2typEU32c9ZxdAXiXURFHuTmeJHhc7cSUtqHdwAsbVWWvEsEddWNAKzkjVPSg2
|
||||
blockHeight: 234015120
|
||||
blockTime: 1701724272
|
||||
attributes:
|
||||
emitterChainId: 2
|
||||
emitterAddress: "0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585"
|
||||
sequence: 144500
|
||||
standardRelayDelivered:
|
||||
name: StandardRelayDelivered
|
||||
title: StandardRelayDelivered
|
||||
contentType: application/json
|
||||
payload:
|
||||
$ref: "#/components/schemas/standardRelayDelivered"
|
||||
examples:
|
||||
- name: StandardRelayDelivered from in Ethereum from Base
|
||||
payload:
|
||||
name: "standard-relay-delivered"
|
||||
address: "0x27428dd2d3dd32a4d7f7c497eaaa23130d894911"
|
||||
chainId: 2
|
||||
txHash: "0xcbdefc83080a8f60cbde7785eb2978548fd5c1f7d0ea2c024cce537845d339c7"
|
||||
blockHeight: 18708316n
|
||||
blockTime: 1699443287
|
||||
attributes:
|
||||
recipientContract: "0xF80cf52922B512B22D46aA8916BD7767524305d9"
|
||||
sourceChain: 30
|
||||
sequence: 2304
|
||||
deliveryVaaHash: "0xf29cac97156fa11c205eda95c0655e4a6e2a9c247245bab4d3d8257c41fc11d2"
|
||||
status: 0
|
||||
gasUsed: 80521
|
||||
refundStatus: 0
|
||||
additionalStatusInfo: "0x"
|
||||
overridesInfo: "0x"
|
||||
schemas:
|
||||
base:
|
||||
type: object
|
||||
|
@ -103,7 +141,37 @@ components:
|
|||
type: string
|
||||
sequence:
|
||||
type: number
|
||||
|
||||
standardRelayDelivered:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/base"
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/chainEventBase"
|
||||
properties:
|
||||
attributes:
|
||||
type: object
|
||||
properties:
|
||||
recipientContract:
|
||||
type: string
|
||||
sourceChain:
|
||||
type: number
|
||||
sequence:
|
||||
type: number
|
||||
deliveryVaaHash:
|
||||
type: string
|
||||
status:
|
||||
type: number
|
||||
gasUsed:
|
||||
type: number
|
||||
refundStatus:
|
||||
type: number
|
||||
additionalStatusInfo:
|
||||
type: string
|
||||
overridesInfo:
|
||||
type: string
|
||||
sentAt:
|
||||
type: string
|
||||
format: date-time
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
{
|
||||
"name": "@wormhole-foundation/blockchain-watcher",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@wormhole-foundation/blockchain-watcher",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-sns": "^3.445.0",
|
||||
"@certusone/wormhole-sdk": "0.10.5",
|
||||
"@types/config": "^3.3.3",
|
||||
"axios": "^1.6.0",
|
||||
"bs58": "^5.0.0",
|
||||
"config": "^3.3.9",
|
||||
|
@ -20,13 +19,12 @@
|
|||
"mollitia": "^0.1.0",
|
||||
"pg": "^8.11.3",
|
||||
"prom-client": "^15.0.0",
|
||||
"uuid": "^9.0.1",
|
||||
"winston": "3.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@testcontainers/postgresql": "^10.3.2",
|
||||
"@types/koa-router": "^7.4.4",
|
||||
"@types/config": "^3.3.3",
|
||||
"@types/pg": "^8.10.9",
|
||||
"@types/uuid": "^9.0.6",
|
||||
"@types/yargs": "^17.0.23",
|
||||
|
@ -4746,15 +4744,6 @@
|
|||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/accepts": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz",
|
||||
"integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz",
|
||||
|
@ -4804,20 +4793,11 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/body-parser": {
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
|
||||
"integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/config": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/config/-/config-3.3.3.tgz",
|
||||
"integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg=="
|
||||
"integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.35",
|
||||
|
@ -4827,24 +4807,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/content-disposition": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz",
|
||||
"integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/cookies": {
|
||||
"version": "0.7.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz",
|
||||
"integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/connect": "*",
|
||||
"@types/express": "*",
|
||||
"@types/keygrip": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/docker-modem": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz",
|
||||
|
@ -4865,30 +4827,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "4.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
|
||||
"integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express-serve-static-core": {
|
||||
"version": "4.17.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz",
|
||||
"integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/graceful-fs": {
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.8.tgz",
|
||||
|
@ -4898,18 +4836,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/http-assert": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz",
|
||||
"integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
|
||||
|
@ -4934,46 +4860,6 @@
|
|||
"@types/istanbul-lib-report": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/keygrip": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
|
||||
"integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/koa": {
|
||||
"version": "2.13.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.6.tgz",
|
||||
"integrity": "sha512-diYUfp/GqfWBAiwxHtYJ/FQYIXhlEhlyaU7lB/bWQrx4Il9lCET5UwpFy3StOAohfsxxvEQ11qIJgT1j2tfBvw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/accepts": "*",
|
||||
"@types/content-disposition": "*",
|
||||
"@types/cookies": "*",
|
||||
"@types/http-assert": "*",
|
||||
"@types/http-errors": "*",
|
||||
"@types/keygrip": "*",
|
||||
"@types/koa-compose": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/koa-compose": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz",
|
||||
"integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/koa-router": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa-router/-/koa-router-7.4.4.tgz",
|
||||
"integrity": "sha512-3dHlZ6CkhgcWeF6wafEUvyyqjWYfKmev3vy1PtOmr0mBc3wpXPU5E8fBBd4YQo5bRpHPfmwC5yDaX7s4jhIN6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
"version": "4.14.195",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz",
|
||||
|
@ -4999,12 +4885,6 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.7.tgz",
|
||||
"integrity": "sha512-gKc9P2d4g5uYwmy4s/MO/yOVPmvHyvzka1YH6i5dM03UrFofHSmgc0D0ymbDRStFWHusk6cwwF6nhLm/ckBbbQ=="
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
|
||||
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.16.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.19.tgz",
|
||||
|
@ -5086,18 +4966,6 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/range-parser": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
||||
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/secp256k1": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
|
||||
|
@ -5106,27 +4974,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/serve-static": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
|
||||
"integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/http-errors": "*",
|
||||
"@types/mime": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ssh2": {
|
||||
"version": "1.11.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.11.18.tgz",
|
||||
|
@ -5157,9 +5004,9 @@
|
|||
"integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g=="
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "9.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz",
|
||||
"integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
|
||||
"version": "9.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz",
|
||||
"integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
|
@ -12200,18 +12047,6 @@
|
|||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
|
@ -16168,15 +16003,6 @@
|
|||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/accepts": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz",
|
||||
"integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/babel__core": {
|
||||
"version": "7.20.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz",
|
||||
|
@ -16226,20 +16052,11 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/body-parser": {
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
|
||||
"integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/config": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/config/-/config-3.3.3.tgz",
|
||||
"integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg=="
|
||||
"integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/connect": {
|
||||
"version": "3.4.35",
|
||||
|
@ -16249,24 +16066,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/content-disposition": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz",
|
||||
"integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/cookies": {
|
||||
"version": "0.7.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz",
|
||||
"integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/connect": "*",
|
||||
"@types/express": "*",
|
||||
"@types/keygrip": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/docker-modem": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz",
|
||||
|
@ -16287,30 +16086,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
|
||||
"integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.17.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz",
|
||||
"integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"@types/graceful-fs": {
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.8.tgz",
|
||||
|
@ -16320,18 +16095,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/http-assert": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz",
|
||||
"integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
|
||||
|
@ -16356,46 +16119,6 @@
|
|||
"@types/istanbul-lib-report": "*"
|
||||
}
|
||||
},
|
||||
"@types/keygrip": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
|
||||
"integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/koa": {
|
||||
"version": "2.13.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.6.tgz",
|
||||
"integrity": "sha512-diYUfp/GqfWBAiwxHtYJ/FQYIXhlEhlyaU7lB/bWQrx4Il9lCET5UwpFy3StOAohfsxxvEQ11qIJgT1j2tfBvw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/accepts": "*",
|
||||
"@types/content-disposition": "*",
|
||||
"@types/cookies": "*",
|
||||
"@types/http-assert": "*",
|
||||
"@types/http-errors": "*",
|
||||
"@types/keygrip": "*",
|
||||
"@types/koa-compose": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/koa-compose": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz",
|
||||
"integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"@types/koa-router": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/koa-router/-/koa-router-7.4.4.tgz",
|
||||
"integrity": "sha512-3dHlZ6CkhgcWeF6wafEUvyyqjWYfKmev3vy1PtOmr0mBc3wpXPU5E8fBBd4YQo5bRpHPfmwC5yDaX7s4jhIN6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/koa": "*"
|
||||
}
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.195",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz",
|
||||
|
@ -16421,12 +16144,6 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.7.tgz",
|
||||
"integrity": "sha512-gKc9P2d4g5uYwmy4s/MO/yOVPmvHyvzka1YH6i5dM03UrFofHSmgc0D0ymbDRStFWHusk6cwwF6nhLm/ckBbbQ=="
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
|
||||
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "18.16.19",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.19.tgz",
|
||||
|
@ -16495,18 +16212,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/range-parser": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
||||
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/secp256k1": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
|
||||
|
@ -16515,27 +16220,6 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/serve-static": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
|
||||
"integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/http-errors": "*",
|
||||
"@types/mime": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/ssh2": {
|
||||
"version": "1.11.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.11.18.tgz",
|
||||
|
@ -16566,9 +16250,9 @@
|
|||
"integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g=="
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "9.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz",
|
||||
"integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
|
||||
"version": "9.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz",
|
||||
"integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/ws": {
|
||||
|
@ -22011,11 +21695,6 @@
|
|||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||
},
|
||||
"v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@wormhole-foundation/blockchain-watcher",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"description": "A process for watching blockchain events and moving them to persistent storage",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -20,7 +20,6 @@
|
|||
"dependencies": {
|
||||
"@aws-sdk/client-sns": "^3.445.0",
|
||||
"@certusone/wormhole-sdk": "0.10.5",
|
||||
"@types/config": "^3.3.3",
|
||||
"axios": "^1.6.0",
|
||||
"bs58": "^5.0.0",
|
||||
"config": "^3.3.9",
|
||||
|
@ -29,17 +28,16 @@
|
|||
"mollitia": "^0.1.0",
|
||||
"pg": "^8.11.3",
|
||||
"prom-client": "^15.0.0",
|
||||
"uuid": "^9.0.1",
|
||||
"winston": "3.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@testcontainers/postgresql": "^10.3.2",
|
||||
"@types/koa-router": "^7.4.4",
|
||||
"@types/pg": "^8.10.9",
|
||||
"@types/uuid": "^9.0.6",
|
||||
"@types/yargs": "^17.0.23",
|
||||
"@vercel/ncc": "^0.38.1",
|
||||
"@types/config": "^3.3.3",
|
||||
"jest": "^29.7.0",
|
||||
"nock": "^13.3.8",
|
||||
"prettier": "^2.8.7",
|
||||
|
@ -83,7 +81,7 @@
|
|||
"coverageDirectory": "./coverage",
|
||||
"coverageThreshold": {
|
||||
"global": {
|
||||
"lines": 73
|
||||
"lines": 75
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ export class PollEvmLogs extends RunPollingJob {
|
|||
toBlock = this.cfg.toBlock;
|
||||
}
|
||||
|
||||
return { fromBlock, toBlock };
|
||||
return { fromBlock: BigInt(fromBlock), toBlock: BigInt(toBlock) };
|
||||
}
|
||||
|
||||
private report(): void {
|
||||
|
@ -124,8 +124,14 @@ export class PollEvmLogs extends RunPollingJob {
|
|||
commitment: this.cfg.getCommitment(),
|
||||
};
|
||||
this.statsRepository.count("job_execution", labels);
|
||||
this.statsRepository.measure("block_height", this.latestBlockHeight ?? 0n, labels);
|
||||
this.statsRepository.measure("block_cursor", this.blockHeightCursor ?? 0n, labels);
|
||||
this.statsRepository.measure("polling_cursor", this.latestBlockHeight ?? 0n, {
|
||||
...labels,
|
||||
type: "max",
|
||||
});
|
||||
this.statsRepository.measure("polling_cursor", this.blockHeightCursor ?? 0n, {
|
||||
...labels,
|
||||
type: "current",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ export * from "./evm/GetEvmLogs";
|
|||
export * from "./evm/PollEvmLogs";
|
||||
export * from "./solana/GetSolanaTransactions";
|
||||
export * from "./solana/PollSolanaTransactions";
|
||||
export * from "./solana/HandleSolanaTransactions";
|
||||
export * from "./RunPollingJob";
|
||||
export * from "./RunCronTask";
|
||||
export * from "./jobs/StartJobs";
|
||||
|
|
|
@ -21,7 +21,7 @@ export class PollSolanaTransactions extends RunPollingJob {
|
|||
statsRepo: StatRepository,
|
||||
cfg: PollSolanaTransactionsConfig
|
||||
) {
|
||||
super(1_000, cfg.id, statsRepo);
|
||||
super(cfg.interval ?? 1_000, cfg.id, statsRepo);
|
||||
|
||||
this.metadataRepo = metadataRepo;
|
||||
this.slotRepository = slotRepo;
|
||||
|
@ -130,8 +130,14 @@ export class PollSolanaTransactions extends RunPollingJob {
|
|||
commitment: this.cfg.commitment,
|
||||
};
|
||||
this.statsRepo.count("job_execution", labels);
|
||||
this.statsRepo.measure("block_height", BigInt(this.latestSlot ?? 0), labels);
|
||||
this.statsRepo.measure("block_cursor", BigInt(this.slotCursor ?? 0n), labels);
|
||||
this.statsRepo.measure("polling_cursor", BigInt(this.latestSlot ?? 0), {
|
||||
...labels,
|
||||
type: "max",
|
||||
});
|
||||
this.statsRepo.measure("polling_cursor", BigInt(this.slotCursor ?? 0n), {
|
||||
...labels,
|
||||
type: "current",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,3 +15,21 @@ export type LogMessagePublished = {
|
|||
payload: string;
|
||||
consistencyLevel: number;
|
||||
};
|
||||
|
||||
export type TransferRedeemed = {
|
||||
emitterChainId: number;
|
||||
emitterAddress: string;
|
||||
sequence: number;
|
||||
};
|
||||
|
||||
export type StandardRelayDelivered = {
|
||||
recipientContract: string;
|
||||
sourceChain: number;
|
||||
sequence: number;
|
||||
deliveryVaaHash: string;
|
||||
status: number;
|
||||
gasUsed: number;
|
||||
refundStatus: number;
|
||||
additionalStatusInfo: string;
|
||||
overridesInfo: string;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { BigNumber } from "ethers";
|
||||
import { EvmLog, LogFoundEvent, StandardRelayDelivered } from "../../domain/entities";
|
||||
|
||||
/*
|
||||
* Delivery (index_topic_1 address recipientContract, index_topic_2 uint16 sourceChain, index_topic_3 uint64 sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)
|
||||
*/
|
||||
export const evmStandardRelayDelivered = (
|
||||
log: EvmLog,
|
||||
args: ReadonlyArray<any>
|
||||
): LogFoundEvent<StandardRelayDelivered> => {
|
||||
if (!log.blockTime) {
|
||||
throw new Error(`Block time is missing for log ${log.logIndex} in tx ${log.transactionHash}`);
|
||||
}
|
||||
|
||||
return {
|
||||
name: "standard-relay-delivered",
|
||||
address: log.address,
|
||||
chainId: log.chainId,
|
||||
txHash: log.transactionHash,
|
||||
blockHeight: log.blockNumber,
|
||||
blockTime: log.blockTime,
|
||||
attributes: {
|
||||
recipientContract: args[0],
|
||||
sourceChain: BigNumber.from(args[1]).toNumber(),
|
||||
sequence: BigNumber.from(args[2]).toNumber(),
|
||||
deliveryVaaHash: args[3],
|
||||
status: BigNumber.from(args[4]).toNumber(),
|
||||
gasUsed: BigNumber.from(args[5]).toNumber(),
|
||||
refundStatus: BigNumber.from(args[6]).toNumber(),
|
||||
additionalStatusInfo: args[7],
|
||||
overridesInfo: args[8],
|
||||
},
|
||||
};
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
import { BigNumber } from "ethers";
|
||||
import { EvmLog, LogFoundEvent, TransferRedeemed } from "../../domain/entities";
|
||||
|
||||
export const evmTransferRedeemedMapper = (
|
||||
log: EvmLog,
|
||||
_: ReadonlyArray<any>
|
||||
): LogFoundEvent<TransferRedeemed> => {
|
||||
if (!log.blockTime) {
|
||||
throw new Error(`Block time is missing for log ${log.logIndex} in tx ${log.transactionHash}`);
|
||||
}
|
||||
|
||||
return {
|
||||
name: "transfer-redeemed",
|
||||
address: log.address,
|
||||
chainId: log.chainId,
|
||||
txHash: log.transactionHash,
|
||||
blockHeight: log.blockNumber,
|
||||
blockTime: log.blockTime,
|
||||
attributes: {
|
||||
emitterChainId: Number(log.topics[1]),
|
||||
emitterAddress: log.topics[2],
|
||||
sequence: BigNumber.from(log.topics[3]).toNumber(),
|
||||
},
|
||||
};
|
||||
};
|
|
@ -1,2 +1,5 @@
|
|||
export * from "./solanaLogMessagePublishedMapper";
|
||||
export * from "./evmLogMessagePublishedMapper";
|
||||
export * from "./evmTransferRedeemedMapper";
|
||||
export * from "./evmStandardRelayDelivered";
|
||||
export * from "./solanaLogMessagePublishedMapper";
|
||||
export * from "./solanaTransferRedeemedMapper";
|
||||
|
|
|
@ -12,7 +12,9 @@ export const solanaLogMessagePublishedMapper = async (
|
|||
{ programId, commitment }: { programId: string; commitment?: Commitment }
|
||||
): Promise<LogFoundEvent<LogMessagePublished>[]> => {
|
||||
if (!tx || !tx.blockTime) {
|
||||
throw new Error(`Block time is missing for tx in slot ${tx?.slot} @ time ${tx?.blockTime}`);
|
||||
throw new Error(
|
||||
`Block time is missing for tx ${tx?.transaction?.signatures} in slot ${tx?.slot}`
|
||||
);
|
||||
}
|
||||
|
||||
const message = tx.transaction.message;
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
import { decode } from "bs58";
|
||||
import { Connection, Commitment } from "@solana/web3.js";
|
||||
import { solana, LogFoundEvent, TransferRedeemed } from "../../domain/entities";
|
||||
import { CompiledInstruction, MessageCompiledInstruction } from "../../domain/entities/solana";
|
||||
import { configuration } from "../config";
|
||||
import { getPostedMessage } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
|
||||
|
||||
enum Instruction {
|
||||
CompleteNativeTransfer = 0x02,
|
||||
CompleteWrappedTransfer = 0x03,
|
||||
CompleteNativeWithPayload = 0x09,
|
||||
CompleteWrappedWithPayload = 0x0a,
|
||||
}
|
||||
|
||||
const connection = new Connection(configuration.chains.solana.rpcs[0]);
|
||||
|
||||
export const solanaTransferRedeemedMapper = async (
|
||||
tx: solana.Transaction,
|
||||
{ programId, commitment }: { programId: string; commitment?: Commitment }
|
||||
): Promise<LogFoundEvent<TransferRedeemed>[]> => {
|
||||
if (!tx || !tx.blockTime) {
|
||||
throw new Error(
|
||||
`Block time is missing for tx ${tx?.transaction?.signatures} in slot ${tx?.slot}`
|
||||
);
|
||||
}
|
||||
|
||||
const message = tx.transaction.message;
|
||||
const accountKeys = message.accountKeys;
|
||||
const programIdIndex = accountKeys.findIndex((i) => i === programId);
|
||||
const instructions = message.compiledInstructions;
|
||||
const innerInstructions =
|
||||
tx.meta?.innerInstructions?.flatMap((i) => i.instructions.map(normalizeCompileInstruction)) ||
|
||||
[];
|
||||
|
||||
const whInstructions = innerInstructions
|
||||
.concat(instructions)
|
||||
.filter((i) => i.programIdIndex === programIdIndex);
|
||||
|
||||
const results: LogFoundEvent<TransferRedeemed>[] = [];
|
||||
for (const instruction of whInstructions) {
|
||||
if (isNotACompleteTransferInstruction(instruction.data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accountAddress = accountKeys[instruction.accountKeyIndexes[2]];
|
||||
const { message } = await getPostedMessage(connection, accountAddress, commitment);
|
||||
const { sequence, emitterAddress, emitterChain } = message || {};
|
||||
|
||||
results.push({
|
||||
name: "transfer-redeemed",
|
||||
address: programId,
|
||||
chainId: 1,
|
||||
txHash: tx.transaction.signatures[0],
|
||||
blockHeight: BigInt(tx.slot.toString()),
|
||||
blockTime: tx.blockTime,
|
||||
attributes: {
|
||||
emitterChainId: emitterChain,
|
||||
emitterAddress: emitterAddress.toString("hex"),
|
||||
sequence: Number(sequence),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
const normalizeCompileInstruction = (
|
||||
instruction: CompiledInstruction | MessageCompiledInstruction
|
||||
): MessageCompiledInstruction => {
|
||||
if ("accounts" in instruction) {
|
||||
return {
|
||||
accountKeyIndexes: instruction.accounts,
|
||||
data: decode(instruction.data),
|
||||
programIdIndex: instruction.programIdIndex,
|
||||
};
|
||||
} else {
|
||||
return instruction;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the instruction is not to complete a transfer.
|
||||
* @param instructionId - the instruction id
|
||||
* @returns true if the instruction is valid, false otherwise
|
||||
*/
|
||||
const isNotACompleteTransferInstruction = (instructionId: Uint8Array): boolean => {
|
||||
return (
|
||||
instructionId[0] !== Instruction.CompleteNativeTransfer &&
|
||||
instructionId[0] !== Instruction.CompleteWrappedTransfer &&
|
||||
instructionId[0] !== Instruction.CompleteNativeWithPayload &&
|
||||
instructionId[0] !== Instruction.CompleteWrappedWithPayload
|
||||
);
|
||||
};
|
|
@ -6,6 +6,7 @@ import {
|
|||
PollSolanaTransactions,
|
||||
PollSolanaTransactionsConfig,
|
||||
RunPollingJob,
|
||||
HandleSolanaTransactions,
|
||||
} from "../../../domain/actions";
|
||||
import { JobDefinition, Handler, LogFoundEvent } from "../../../domain/entities";
|
||||
import {
|
||||
|
@ -15,10 +16,15 @@ import {
|
|||
SolanaSlotRepository,
|
||||
StatRepository,
|
||||
} from "../../../domain/repositories";
|
||||
import { FileMetadataRepository, SnsEventRepository } from "../index";
|
||||
import { HandleSolanaTransactions } from "../../../domain/actions/solana/HandleSolanaTransactions";
|
||||
import { solanaLogMessagePublishedMapper, evmLogMessagePublishedMapper } from "../../mappers";
|
||||
import log from "../../log";
|
||||
import { FileMetadataRepository, SnsEventRepository } from "..";
|
||||
import {
|
||||
solanaLogMessagePublishedMapper,
|
||||
solanaTransferRedeemedMapper,
|
||||
evmLogMessagePublishedMapper,
|
||||
evmStandardRelayDelivered,
|
||||
evmTransferRedeemedMapper,
|
||||
} from "../../mappers";
|
||||
|
||||
export class StaticJobRepository implements JobRepository {
|
||||
private fileRepo: FileMetadataRepository;
|
||||
|
@ -112,7 +118,10 @@ export class StaticJobRepository implements JobRepository {
|
|||
|
||||
// Mappers
|
||||
this.mappers.set("evmLogMessagePublishedMapper", evmLogMessagePublishedMapper);
|
||||
this.mappers.set("evmStandardRelayDelivered", evmStandardRelayDelivered);
|
||||
this.mappers.set("evmTransferRedeemedMapper", evmTransferRedeemedMapper);
|
||||
this.mappers.set("solanaLogMessagePublishedMapper", solanaLogMessagePublishedMapper);
|
||||
this.mappers.set("solanaTransferRedeemedMapper", solanaTransferRedeemedMapper);
|
||||
|
||||
// Targets
|
||||
const snsTarget = () => this.snsRepo.asTarget();
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import { describe, it, expect } from "@jest/globals";
|
||||
import { evmStandardRelayDelivered } from "../../../src/infrastructure/mappers/evmStandardRelayDelivered";
|
||||
import { HandleEvmLogs } from "../../../src/domain/actions";
|
||||
|
||||
const address = "0x27428dd2d3dd32a4d7f7c497eaaa23130d894911";
|
||||
const topic = "0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e";
|
||||
const txHash = "0xcbdefc83080a8f60cbde7785eb2978548fd5c1f7d0ea2c024cce537845d339c7";
|
||||
|
||||
const handler = new HandleEvmLogs(
|
||||
{
|
||||
filter: { addresses: [address], topics: [topic] },
|
||||
abi: "event Delivery(address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, uint8 status, uint256 gasUsed, uint8 refundStatus, bytes additionalStatusInfo, bytes overridesInfo)",
|
||||
},
|
||||
evmStandardRelayDelivered,
|
||||
async () => {}
|
||||
);
|
||||
|
||||
describe("evmStandardRelayDelivered", () => {
|
||||
it("should be able to map log to TransferRedeeemed", async () => {
|
||||
const [result] = await handler.handle([
|
||||
{
|
||||
chainId: 2,
|
||||
address,
|
||||
blockTime: 1699443287,
|
||||
transactionHash: txHash,
|
||||
topics: [
|
||||
"0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e",
|
||||
"0x000000000000000000000000f80cf52922b512b22d46aa8916bd7767524305d9",
|
||||
"0x000000000000000000000000000000000000000000000000000000000000001e",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000900",
|
||||
],
|
||||
data: "0xf29cac97156fa11c205eda95c0655e4a6e2a9c247245bab4d3d8257c41fc11d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013a89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
blockNumber: 18708316n,
|
||||
transactionIndex: "0x3b",
|
||||
blockHash: "0x8c55cbd97c96f8322bed4d1790c7ac4a84b1cff46c157bf86fc35eb5886be451",
|
||||
logIndex: 5,
|
||||
removed: false,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(result.name).toBe("standard-relay-delivered");
|
||||
expect(result.chainId).toBe(2);
|
||||
expect(result.txHash).toBe(txHash);
|
||||
expect(result.blockHeight).toBe(18708316n);
|
||||
expect(result.blockTime).toBe(1699443287);
|
||||
|
||||
expect(result.attributes.recipientContract.toLowerCase()).toBe(
|
||||
"0xf80cf52922b512b22d46aa8916bd7767524305d9"
|
||||
);
|
||||
expect(result.attributes.sourceChain).toBe(30);
|
||||
expect(result.attributes.sequence).toBe(2304);
|
||||
expect(result.attributes.deliveryVaaHash.toLowerCase()).toBe(
|
||||
"0xf29cac97156fa11c205eda95c0655e4a6e2a9c247245bab4d3d8257c41fc11d2"
|
||||
);
|
||||
expect(result.attributes.status).toBe(0);
|
||||
expect(result.attributes.gasUsed).toBe(80521);
|
||||
expect(result.attributes.refundStatus).toBe(0);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
import { describe, it, expect } from "@jest/globals";
|
||||
import { evmTransferRedeemedMapper } from "../../../src/infrastructure/mappers/evmTransferRedeemedMapper";
|
||||
import { HandleEvmLogs } from "../../../src/domain/actions";
|
||||
|
||||
const address = "0x98f3c9e6e3face36baad05fe09d375ef1464288b";
|
||||
const topic = "0xcaf280c8cfeba144da67230d9b009c8f868a75bac9a528fa0474be1ba317c169";
|
||||
const txHash = "0xcbdefc83080a8f60cbde7785eb2978548fd5c1f7d0ea2c024cce537845d339c7";
|
||||
|
||||
const handler = new HandleEvmLogs(
|
||||
{
|
||||
filter: { addresses: [address], topics: [topic] },
|
||||
abi: "event TransferRedeemed(uint16 indexed emitterChainId, bytes32 indexed emitterAddress, uint64 indexed sequence)",
|
||||
},
|
||||
evmTransferRedeemedMapper,
|
||||
async () => {}
|
||||
);
|
||||
|
||||
describe("evmTransferRedeemed", () => {
|
||||
it("should be able to map log to TransferRedeeemed", async () => {
|
||||
const [result] = await handler.handle([
|
||||
{
|
||||
chainId: 2,
|
||||
address,
|
||||
topics: [
|
||||
"0xcaf280c8cfeba144da67230d9b009c8f868a75bac9a528fa0474be1ba317c169",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"0xec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000052a3e",
|
||||
],
|
||||
data: "0x",
|
||||
blockNumber: 18708192n,
|
||||
blockTime: 1699443287,
|
||||
transactionHash: txHash,
|
||||
transactionIndex: "0x3e",
|
||||
blockHash: "0x241fa85f3494c654d59859b46af586bd43f37ec434f5cf0018a53e46c42da393",
|
||||
logIndex: 216,
|
||||
removed: false,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(result.name).toBe("transfer-redeemed");
|
||||
expect(result.chainId).toBe(2);
|
||||
expect(result.txHash).toBe(txHash);
|
||||
expect(result.blockHeight).toBe(18708192n);
|
||||
expect(result.blockTime).toBe(1699443287);
|
||||
|
||||
expect(result.attributes.sequence).toBe(338494);
|
||||
expect(result.attributes.emitterAddress.toLowerCase()).toBe(
|
||||
"0xec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5"
|
||||
);
|
||||
expect(result.attributes.emitterChainId).toBe(1);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,356 @@
|
|||
import { expect, describe, it, jest } from "@jest/globals";
|
||||
import { solana } from "../../../src/domain/entities";
|
||||
import { solanaTransferRedeemedMapper } from "../../../src/infrastructure/mappers";
|
||||
import { getPostedMessage } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
|
||||
|
||||
jest.mock("@certusone/wormhole-sdk/lib/cjs/solana/wormhole");
|
||||
|
||||
describe("solanaTransferRedeemedMapper", () => {
|
||||
it("should map a token bridge tx to a transfer-redeemed event", async () => {
|
||||
const mockGetPostedMessage = getPostedMessage as jest.MockedFunction<typeof getPostedMessage>;
|
||||
mockGetPostedMessage.mockResolvedValueOnce({
|
||||
message: {
|
||||
emitterChain: 2,
|
||||
sequence: 1500n,
|
||||
emitterAddress: Buffer.from(
|
||||
"0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585",
|
||||
"hex"
|
||||
),
|
||||
submissionTime: 1700571923,
|
||||
nonce: 0,
|
||||
consistencyLevel: 1,
|
||||
payload: Buffer.from("41QVZTrdrRxb", "base64"),
|
||||
} as any,
|
||||
});
|
||||
|
||||
const programId = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb";
|
||||
const tx = {
|
||||
blockTime: 1701724272,
|
||||
meta: {
|
||||
innerInstructions: [
|
||||
{
|
||||
index: 0,
|
||||
instructions: [
|
||||
{
|
||||
accounts: [0, 3],
|
||||
data: "3Bxs49175da2o1zw",
|
||||
programIdIndex: 4,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [3],
|
||||
data: "9krTCzbLfv4BRBcj",
|
||||
programIdIndex: 4,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [3],
|
||||
data: "SYXsBvR59hMYH7jGFg8pjr13roqCKDy5t1HFBVKFNWZ1FPp7",
|
||||
programIdIndex: 4,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [2, 1, 6],
|
||||
data: "6jFrQ56LiKZ1",
|
||||
programIdIndex: 11,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [2, 1, 6],
|
||||
data: "6AjePwYNteRu",
|
||||
programIdIndex: 11,
|
||||
stackHeight: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
logMessages: [
|
||||
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb invoke [1]",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: MintTo",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4492 of 136305 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: MintTo",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4589 of 125187 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb consumed 80797 of 200000 compute units",
|
||||
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb success",
|
||||
],
|
||||
status: {
|
||||
Ok: null,
|
||||
},
|
||||
},
|
||||
slot: 234015120,
|
||||
transaction: {
|
||||
message: {
|
||||
header: {
|
||||
numReadonlySignedAccounts: 0,
|
||||
numReadonlyUnsignedAccounts: 10,
|
||||
numRequiredSignatures: 1,
|
||||
},
|
||||
accountKeys: [
|
||||
"7dm9am6Qx7cH64RB99Mzf7ZsLbEfmXM7ihXXCvMiT2X1",
|
||||
"4RrFMkY3A5zWdizT61Px222qmSTJqnVszDeBZZNSoAH6",
|
||||
"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
|
||||
"HkpTbh5td45g3SfFsKmjukX2YZUKfEHZG5HfRrw6Tkyi",
|
||||
"11111111111111111111111111111111",
|
||||
"2gQuwC9GMUCVcXw9VffeCswhKbPeyzHH9ZPEnRBw4K9w",
|
||||
"BCD75RNBHrJJpW4dXVagL5mPjzRLnVZq4YirJdjEYMV7",
|
||||
"CvYA8s1SnSzQzCv71rjt7Sc9iEVNjz2exRpoucyH2RCE",
|
||||
"DapiQYH3BGonhN8cngWcXQ6SrqSm3cwysoznoHr6Sbsx",
|
||||
"DujfLgMKW71CT2W8pxknf42FT86VbcK5PjQ6LsutjWKC",
|
||||
"SysvarRent111111111111111111111111111111111",
|
||||
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
|
||||
"worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth",
|
||||
"wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb",
|
||||
],
|
||||
recentBlockhash: "H9bDwcfav3nq9wvzJi9sEPCm4oHxqS59nZU81mncD6AU",
|
||||
instructions: [
|
||||
{
|
||||
accounts: [0, 8, 7, 3, 9, 1, 1, 2, 5, 6, 10, 4, 11, 12],
|
||||
data: "4",
|
||||
programIdIndex: 13,
|
||||
stackHeight: null,
|
||||
},
|
||||
],
|
||||
indexToProgramIds: {},
|
||||
compiledInstructions: [
|
||||
{
|
||||
programIdIndex: 13,
|
||||
accountKeyIndexes: [0, 8, 7, 3, 9, 1, 1, 2, 5, 6, 10, 4, 11, 12],
|
||||
data: new Uint8Array([3]),
|
||||
},
|
||||
],
|
||||
},
|
||||
signatures: [
|
||||
"3FySmshUgVCM2N158oNYbeTfZt2typEU32c9ZxdAXiXURFHuTmeJHhc7cSUtqHdwAsbVWWvEsEddWNAKzkjVPSg2",
|
||||
],
|
||||
},
|
||||
version: "legacy",
|
||||
} as any as solana.Transaction;
|
||||
|
||||
const events = await solanaTransferRedeemedMapper(tx, { programId });
|
||||
|
||||
expect(events).toHaveLength(1);
|
||||
expect(events[0].name).toBe("transfer-redeemed");
|
||||
expect(events[0].address).toBe(programId);
|
||||
expect(events[0].chainId).toBe(1);
|
||||
expect(events[0].txHash).toBe(tx.transaction.signatures[0]);
|
||||
expect(events[0].blockHeight).toBe(BigInt(tx.slot));
|
||||
expect(events[0].blockTime).toBe(tx.blockTime);
|
||||
});
|
||||
|
||||
it("should map a tx involving token bridge relayer (aka connect) to a transfer-redeemed event", async () => {
|
||||
const mockGetPostedMessage = getPostedMessage as jest.MockedFunction<typeof getPostedMessage>;
|
||||
mockGetPostedMessage.mockResolvedValueOnce({
|
||||
message: {
|
||||
emitterChain: 4,
|
||||
sequence: 5185,
|
||||
emitterAddress: Buffer.from(
|
||||
"0000000000000000000000009dcf9d205c9de35334d646bee44b2d2859712a09",
|
||||
"hex"
|
||||
),
|
||||
submissionTime: 1700571923,
|
||||
nonce: 0,
|
||||
consistencyLevel: 1,
|
||||
payload: Buffer.from("41QVZTrdrRxb", "base64"),
|
||||
} as any,
|
||||
});
|
||||
|
||||
const programId = "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe";
|
||||
const tx = {
|
||||
blockTime: 1701701948,
|
||||
meta: {
|
||||
innerInstructions: [
|
||||
{
|
||||
index: 0,
|
||||
instructions: [
|
||||
{
|
||||
accounts: [0, 1],
|
||||
data: "11119os1e9qSs2u7TsThXqkBSRVFxhmYaFKFZ1waB2X7armDmvK3p5GmLdUxYdg3h7QSrL",
|
||||
programIdIndex: 7,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [1, 4],
|
||||
data: "6NejZzEkDLeuHiYpvQR3Ck46Sw6FQeXFmX5TGWpBSLgJ1",
|
||||
programIdIndex: 22,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [0, 15, 8, 5, 16, 1, 9, 1, 4, 12, 20, 21, 7, 11, 22],
|
||||
data: "B",
|
||||
programIdIndex: 18,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [0, 5],
|
||||
data: "11112ncWAFpbecrgZiGiLpaHnEYkj7ECUfBBRHr4H5tFCq9bHFXWRyWUjj586frtFc19oa",
|
||||
programIdIndex: 7,
|
||||
stackHeight: 3,
|
||||
},
|
||||
{
|
||||
accounts: [4, 1, 20],
|
||||
data: "6j1A9VR8zuFm",
|
||||
programIdIndex: 22,
|
||||
stackHeight: 3,
|
||||
},
|
||||
{
|
||||
accounts: [1, 2, 9],
|
||||
data: "3tMLEJ9BQpG7",
|
||||
programIdIndex: 22,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [1, 6, 9],
|
||||
data: "3qeniiQUmAqm",
|
||||
programIdIndex: 22,
|
||||
stackHeight: 2,
|
||||
},
|
||||
{
|
||||
accounts: [1, 0, 9],
|
||||
data: "A",
|
||||
programIdIndex: 22,
|
||||
stackHeight: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
loadedAddresses: {
|
||||
readonly: [],
|
||||
writable: [],
|
||||
},
|
||||
logMessages: [
|
||||
"Program 3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg invoke [1]",
|
||||
"Program log: Instruction: CompleteWrappedTransferWithRelay",
|
||||
"Program 11111111111111111111111111111111 invoke [2]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: InitializeAccount3",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4214 of 223786 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe invoke [2]",
|
||||
"Program log: Instruction: LegacyCompleteTransferWithPayloadWrapped",
|
||||
"Program 11111111111111111111111111111111 invoke [3]",
|
||||
"Program 11111111111111111111111111111111 success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
|
||||
"Program log: Instruction: MintTo",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4492 of 128286 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe consumed 50570 of 173121 compute units",
|
||||
"Program DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 119156 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: Transfer",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 111686 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
|
||||
"Program log: Instruction: CloseAccount",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3015 of 104235 compute units",
|
||||
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
|
||||
"Program 3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg consumed 150503 of 250000 compute units",
|
||||
"Program 3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg success",
|
||||
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
|
||||
"Program ComputeBudget111111111111111111111111111111 success",
|
||||
],
|
||||
status: {
|
||||
Ok: null,
|
||||
},
|
||||
},
|
||||
slot: 262968784,
|
||||
transaction: {
|
||||
message: {
|
||||
header: {
|
||||
numReadonlySignedAccounts: 0,
|
||||
numReadonlyUnsignedAccounts: 16,
|
||||
numRequiredSignatures: 1,
|
||||
},
|
||||
accountKeys: [
|
||||
"hiUN9rS9VTPVGYc71Vf2d6iyFLvsQaSsqWhxydqdaZf",
|
||||
"14UpGeFGK9iEhVTgMbdd7RHZmBKb8BYxBpAYGtBWigeT",
|
||||
"3pjtJPtu7Z9NzQinCaaRyUsZPwSrNjGxYi7RMwkigk47",
|
||||
"8DW7zrpEe9EVxbD8PBfmEKNkCwXPFTVVukHXirrcE9iV",
|
||||
"BaGfF51MQ3a61papTRDYaNefBgTQ9ywnVne5fCff4bxT",
|
||||
"bMDMKEYXfWM2h5AyJL4kzBXLr8Wms29NSWeGQGLgEad",
|
||||
"EGdE1V4GLFyZH5FFDtsxZaRkw84WhwPWJkCV4yT2L6F4",
|
||||
"11111111111111111111111111111111",
|
||||
"2EqgRpRxi1MR8QLycFDcMKws1Kv56dQcwSmXKkFJZgnW",
|
||||
"2X2u43DR3odTT4jQKFqsG5f4SCfbEmz4pAHR2EVd3Xs3",
|
||||
"3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg",
|
||||
"3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5",
|
||||
"5rmBUDWruRcWU4S4JyjPLZhcYJARYw4FeU9brEo4nUzo",
|
||||
"7pFgBNscwYBfKs1Bsi7wgyibmtNCmK4442pgL4xiJcTr",
|
||||
"8huuoQHYxWGs3oYoKXJBsBgPousVa9XfkPyHWrpPH1B8",
|
||||
"8PFZNjn19BBYVHNp4H31bEW7eAmu78Yf2RKV8EeA461K",
|
||||
"9A7Z7kJw7hPsBJQDSeFU63DsgZGhSTjXmGLYS81yCHBN",
|
||||
"ComputeBudget111111111111111111111111111111",
|
||||
"DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe",
|
||||
"HeMY4WFgEA8zkbp7HMCma5mswLArPzPe53EkYcXDJTUV",
|
||||
"rRsXLHe7sBHdyKU3KY3wbcgWvoT1Ntqudf6e9PKusgb",
|
||||
"SysvarRent111111111111111111111111111111111",
|
||||
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
|
||||
],
|
||||
recentBlockhash: "KVvqcsFkfd4mgWjqjsEATKvciAwCwUgdeVHeRh4LqyT",
|
||||
instructions: [
|
||||
{
|
||||
accounts: [0, 9, 2, 19, 4, 6, 3, 13, 14, 1, 12, 15, 8, 5, 16, 20, 11, 18, 7, 22, 21],
|
||||
data: "9ewcWKkpwjKSXZao88ZRqjejhWC1Bf6cFzdxHbDN4taHHCL3zM9P3xi",
|
||||
programIdIndex: 10,
|
||||
stackHeight: null,
|
||||
},
|
||||
{
|
||||
accounts: [],
|
||||
data: "HnkkG7",
|
||||
programIdIndex: 17,
|
||||
stackHeight: null,
|
||||
},
|
||||
],
|
||||
indexToProgramIds: {},
|
||||
compiledInstructions: [
|
||||
{
|
||||
programIdIndex: 10,
|
||||
accountKeyIndexes: [
|
||||
0, 9, 2, 19, 4, 6, 3, 13, 14, 1, 12, 15, 8, 5, 16, 20, 11, 18, 7, 22, 21,
|
||||
],
|
||||
data: new Uint8Array([
|
||||
174, 44, 4, 91, 81, 201, 235, 255, 59, 128, 71, 194, 194, 46, 49, 88, 200, 5, 254,
|
||||
175, 217, 196, 30, 63, 1, 233, 245, 96, 162, 12, 73, 62, 205, 171, 142, 159, 18, 6,
|
||||
57, 151,
|
||||
]),
|
||||
},
|
||||
{
|
||||
programIdIndex: 17,
|
||||
accountKeyIndexes: [],
|
||||
data: new Uint8Array([2, 144, 208, 3, 0]),
|
||||
},
|
||||
],
|
||||
},
|
||||
signatures: [
|
||||
"5Cu3tD15AtcQ5NGK6PFT9UMVmqh94ARz8FXpFts5G1nNzQnXXaugP3ELa79P9xCwESC5Kw7FtGHUgh7vz8DuP8tM",
|
||||
],
|
||||
},
|
||||
|
||||
version: "legacy",
|
||||
} as any as solana.Transaction;
|
||||
|
||||
const events = await solanaTransferRedeemedMapper(tx, { programId });
|
||||
|
||||
expect(events).toHaveLength(1);
|
||||
expect(events[0].name).toBe("transfer-redeemed");
|
||||
expect(events[0].address).toBe(programId);
|
||||
expect(events[0].chainId).toBe(1);
|
||||
expect(events[0].txHash).toBe(tx.transaction.signatures[0]);
|
||||
expect(events[0].blockHeight).toBe(BigInt(tx.slot));
|
||||
expect(events[0].blockTime).toBe(tx.blockTime);
|
||||
});
|
||||
});
|
|
@ -37,6 +37,12 @@ var ETHEREUM_MAINNET = WatcherBlockchainAddresses{
|
|||
Name: MetehodCompleteTransferWithRelay,
|
||||
},
|
||||
},
|
||||
strings.ToLower("0xd8E1465908103eD5fd28e381920575fb09beb264"): {
|
||||
{
|
||||
ID: MethodIDReceiveMessageAndSwap,
|
||||
Name: MethodReceiveMessageAndSwap,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -77,6 +83,12 @@ var POLYGON_MAINNET = WatcherBlockchainAddresses{
|
|||
Name: MethodReceiveTbtc,
|
||||
},
|
||||
},
|
||||
strings.ToLower("0xf6C5FD2C8Ecba25420859f61Be0331e68316Ba01"): {
|
||||
{
|
||||
ID: MethodIDReceiveMessageAndSwap,
|
||||
Name: MethodReceiveMessageAndSwap,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -318,6 +330,12 @@ var ARBITRUM_MAINNET = WatcherBlockchainAddresses{
|
|||
Name: MethodReceiveTbtc,
|
||||
},
|
||||
},
|
||||
strings.ToLower("0xf8497FE5B0C5373778BFa0a001d476A21e01f09b"): {
|
||||
{
|
||||
ID: MethodIDReceiveMessageAndSwap,
|
||||
Name: MethodReceiveMessageAndSwap,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -334,6 +352,12 @@ var OPTIMISM_MAINNET = WatcherBlockchainAddresses{
|
|||
Name: MethodReceiveTbtc,
|
||||
},
|
||||
},
|
||||
strings.ToLower("0xcF205Fa51D33280D9B70321Ae6a3686FB2c178b2"): {
|
||||
{
|
||||
ID: MethodIDReceiveMessageAndSwap,
|
||||
Name: MethodReceiveMessageAndSwap,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -366,5 +390,11 @@ var BASE_MAINNET = WatcherBlockchainAddresses{
|
|||
Name: MetehodCompleteTransferWithRelay,
|
||||
},
|
||||
},
|
||||
strings.ToLower("0x9816d7C448f79CdD4aF18c4Ae1726A14299E8C75"): {
|
||||
{
|
||||
ID: MethodIDReceiveMessageAndSwap,
|
||||
Name: MethodReceiveMessageAndSwap,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ const (
|
|||
//Method name for wormhole tBTC gateway
|
||||
MethodReceiveTbtc = "receiveTbtc"
|
||||
|
||||
//Method name for Portico contract
|
||||
MethodReceiveMessageAndSwap = "receiveMessageAndSwap"
|
||||
|
||||
//Method ids for wormhole token bridge contract
|
||||
MethodIDCompleteTransfer = "0xc6878519"
|
||||
MethodIDWrapAndTransfer = "0x9981509f"
|
||||
|
@ -31,6 +34,9 @@ const (
|
|||
|
||||
//Method id for wormhole tBTC gateway
|
||||
MethodIDReceiveTbtc = "0x5d21a596"
|
||||
|
||||
//Method id for Portico contract
|
||||
MethodIDReceiveMessageAndSwap = "0x3d528f35"
|
||||
)
|
||||
|
||||
type WatcherBlockchain struct {
|
||||
|
|
|
@ -269,8 +269,8 @@ data:
|
|||
"config": {
|
||||
"blockBatchSize": 100,
|
||||
"commitment": "latest",
|
||||
"interval": 5000,
|
||||
"addresses": ["0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B"],
|
||||
"interval": 15000,
|
||||
"addresses": ["0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B", "0x27428dd2d3dd32a4d7f7c497eaaa23130d894911", "0x3ee18b2214aff97000d974cf647e7c347e8fa585"],
|
||||
"chain": "ethereum"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -61,6 +61,31 @@ data:
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "poll-transfer-redeemed-solana",
|
||||
"chain": "solana",
|
||||
"source": {
|
||||
"action": "PollSolanaTransactions",
|
||||
"config": {
|
||||
"slotBatchSize": 1000,
|
||||
"commitment": "finalized",
|
||||
"interval": 5000,
|
||||
"signaturesLimit": 100,
|
||||
"programId": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe",
|
||||
"chain": "solana"
|
||||
}
|
||||
},
|
||||
"handlers": [
|
||||
{
|
||||
"action": "HandleSolanaTransactions",
|
||||
"target": "sns",
|
||||
"mapper": "solanaTransferRedeemedMapper",
|
||||
"config": {
|
||||
"programId": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
mainnet-jobs.json: |-
|
||||
|
@ -71,9 +96,9 @@ data:
|
|||
"source": {
|
||||
"action": "PollSolanaTransactions",
|
||||
"config": {
|
||||
"slotBatchSize": 2000,
|
||||
"slotBatchSize": 1000,
|
||||
"commitment": "finalized",
|
||||
"interval": 3500,
|
||||
"interval": 1500,
|
||||
"signaturesLimit": 200,
|
||||
"programId": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth",
|
||||
"chain": "solana"
|
||||
|
@ -89,6 +114,31 @@ data:
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "poll-transfer-redeemed-solana",
|
||||
"chain": "solana",
|
||||
"source": {
|
||||
"action": "PollSolanaTransactions",
|
||||
"config": {
|
||||
"slotBatchSize": 1000,
|
||||
"commitment": "finalized",
|
||||
"interval": 1500,
|
||||
"signaturesLimit": 200,
|
||||
"programId": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb",
|
||||
"chain": "solana"
|
||||
}
|
||||
},
|
||||
"handlers": [
|
||||
{
|
||||
"action": "HandleSolanaTransactions",
|
||||
"target": "sns",
|
||||
"mapper": "solanaTransferRedeemedMapper",
|
||||
"config": {
|
||||
"programId": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
---
|
||||
|
|
Loading…
Reference in New Issue