From 79753f17f6ba22ada3e367a902d9942135ee1d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix?= Date: Mon, 14 Oct 2024 18:58:08 +0200 Subject: [PATCH] Not working --- .pnp.cjs | 97 ++++++++----- .vscode/settings.json | 2 + Anchor.toml | 6 +- Cargo.lock | 12 +- sdk/solana/package.json | 10 +- sdk/solana/tbrv3/bpf-loader-upgradeable.ts | 8 +- sdk/solana/tbrv3/idl/token_bridge_relayer.ts | 131 +++++++++--------- sdk/solana/tbrv3/token-bridge-relayer.ts | 113 ++++++++------- solana/package.json | 8 +- .../programs/token-bridge-relayer/Cargo.toml | 19 ++- solana/programs/token-bridge-relayer/build.rs | 110 +++++++++++++++ .../token-bridge-relayer/network.json | 14 ++ .../programs/token-bridge-relayer/src/lib.rs | 17 +-- .../src/processor/inbound.rs | 2 +- .../src/processor/outbound.rs | 8 +- .../src/processor/queries.rs | 8 +- .../token-bridge-relayer/src/utils.rs | 10 +- .../test-program-keypair.json} | 0 solana/tests/token-bridge-relayer-tests.ts | 57 +++++--- solana/tests/utils/client-wrapper.ts | 30 ++-- solana/tests/utils/helpers.ts | 37 ++--- solana/tsconfig.json | 6 +- target/idl/token_bridge_relayer.json | 131 +++++++++--------- target/types/token_bridge_relayer.ts | 131 +++++++++--------- yarn.lock | 103 +++++++++----- 25 files changed, 632 insertions(+), 438 deletions(-) create mode 100644 solana/programs/token-bridge-relayer/build.rs create mode 100644 solana/programs/token-bridge-relayer/network.json rename solana/{tests/program.json => programs/token-bridge-relayer/test-program-keypair.json} (100%) diff --git a/.pnp.cjs b/.pnp.cjs index 0bc7bc91..a2614124 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -2105,18 +2105,18 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@wormhole-foundation/sdk-base", [\ - ["npm:0.10.5", {\ - "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-base-npm-0.10.5-34b63ded35-621cd97edc.zip/node_modules/@wormhole-foundation/sdk-base/",\ + ["npm:0.10.9", {\ + "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-base-npm-0.10.9-1a809728e8-b385ba242c.zip/node_modules/@wormhole-foundation/sdk-base/",\ "packageDependencies": [\ - ["@wormhole-foundation/sdk-base", "npm:0.10.5"],\ + ["@wormhole-foundation/sdk-base", "npm:0.10.9"],\ ["@scure/base", "npm:1.1.8"]\ ],\ "linkType": "HARD"\ }],\ - ["npm:0.10.9", {\ - "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-base-npm-0.10.9-1a809728e8-b385ba242c.zip/node_modules/@wormhole-foundation/sdk-base/",\ + ["npm:0.11.0", {\ + "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-base-npm-0.11.0-4230e2e743-5ff3faf68d.zip/node_modules/@wormhole-foundation/sdk-base/",\ "packageDependencies": [\ - ["@wormhole-foundation/sdk-base", "npm:0.10.9"],\ + ["@wormhole-foundation/sdk-base", "npm:0.11.0"],\ ["@scure/base", "npm:1.1.8"]\ ],\ "linkType": "HARD"\ @@ -2132,6 +2132,16 @@ const RAW_RUNTIME_STATE = ["axios", "npm:1.7.7"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:0.11.0", {\ + "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-connect-npm-0.11.0-0acb45268f-475bcc4f32.zip/node_modules/@wormhole-foundation/sdk-connect/",\ + "packageDependencies": [\ + ["@wormhole-foundation/sdk-connect", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-base", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-definitions", "npm:0.11.0"],\ + ["axios", "npm:1.7.7"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@wormhole-foundation/sdk-definitions", [\ @@ -2144,6 +2154,16 @@ const RAW_RUNTIME_STATE = ["@wormhole-foundation/sdk-base", "npm:0.10.9"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:0.11.0", {\ + "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-definitions-npm-0.11.0-605dfa6baa-f6f4c84d48.zip/node_modules/@wormhole-foundation/sdk-definitions/",\ + "packageDependencies": [\ + ["@wormhole-foundation/sdk-definitions", "npm:0.11.0"],\ + ["@noble/curves", "npm:1.6.0"],\ + ["@noble/hashes", "npm:1.5.0"],\ + ["@wormhole-foundation/sdk-base", "npm:0.11.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@wormhole-foundation/sdk-evm", [\ @@ -2170,33 +2190,46 @@ const RAW_RUNTIME_STATE = ["rpc-websockets", "npm:7.11.2"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:0.11.0", {\ + "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-solana-npm-0.11.0-bb8c4494ce-2134057b9e.zip/node_modules/@wormhole-foundation/sdk-solana/",\ + "packageDependencies": [\ + ["@wormhole-foundation/sdk-solana", "npm:0.11.0"],\ + ["@coral-xyz/anchor", "npm:0.29.0"],\ + ["@coral-xyz/borsh", "virtual:852da326f150408584798524fe58e9855b987bcc4f041389e1ca13248c23c659c3ffb4a9aa4176cc7542f503f2e1e6422a1f18f69e5e623ca255691d222a55ca#npm:0.29.0"],\ + ["@solana/spl-token", "virtual:97362ecb14e50e20b7ada67ad3a152b436c697b1dcabeff3222cb21c9eb5f17ed8db342f5bd1d33187364c1da3f858a18efe787303ea575ea75b39a54056acb6#npm:0.3.9"],\ + ["@solana/web3.js", "npm:1.95.3"],\ + ["@wormhole-foundation/sdk-connect", "npm:0.11.0"],\ + ["rpc-websockets", "npm:7.11.2"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@wormhole-foundation/sdk-solana-core", [\ - ["npm:0.10.9", {\ - "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-solana-core-npm-0.10.9-7f5a2f653d-9615359173.zip/node_modules/@wormhole-foundation/sdk-solana-core/",\ + ["npm:0.11.0", {\ + "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-solana-core-npm-0.11.0-7e7836349d-8174385288.zip/node_modules/@wormhole-foundation/sdk-solana-core/",\ "packageDependencies": [\ - ["@wormhole-foundation/sdk-solana-core", "npm:0.10.9"],\ + ["@wormhole-foundation/sdk-solana-core", "npm:0.11.0"],\ ["@coral-xyz/anchor", "npm:0.29.0"],\ ["@coral-xyz/borsh", "virtual:852da326f150408584798524fe58e9855b987bcc4f041389e1ca13248c23c659c3ffb4a9aa4176cc7542f503f2e1e6422a1f18f69e5e623ca255691d222a55ca#npm:0.29.0"],\ ["@solana/web3.js", "npm:1.95.3"],\ - ["@wormhole-foundation/sdk-connect", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-solana", "npm:0.10.9"]\ + ["@wormhole-foundation/sdk-connect", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-solana", "npm:0.11.0"]\ ],\ "linkType": "HARD"\ }]\ ]],\ ["@wormhole-foundation/sdk-solana-tokenbridge", [\ - ["npm:0.10.9", {\ - "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-solana-tokenbridge-npm-0.10.9-1df657cf0b-4c722bfc07.zip/node_modules/@wormhole-foundation/sdk-solana-tokenbridge/",\ + ["npm:0.11.0", {\ + "packageLocation": "./.yarn/cache/@wormhole-foundation-sdk-solana-tokenbridge-npm-0.11.0-db2164c1f9-bcc313d424.zip/node_modules/@wormhole-foundation/sdk-solana-tokenbridge/",\ "packageDependencies": [\ - ["@wormhole-foundation/sdk-solana-tokenbridge", "npm:0.10.9"],\ + ["@wormhole-foundation/sdk-solana-tokenbridge", "npm:0.11.0"],\ ["@coral-xyz/anchor", "npm:0.29.0"],\ ["@solana/spl-token", "virtual:97362ecb14e50e20b7ada67ad3a152b436c697b1dcabeff3222cb21c9eb5f17ed8db342f5bd1d33187364c1da3f858a18efe787303ea575ea75b39a54056acb6#npm:0.3.9"],\ ["@solana/web3.js", "npm:1.95.3"],\ - ["@wormhole-foundation/sdk-connect", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-solana", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-solana-core", "npm:0.10.9"]\ + ["@wormhole-foundation/sdk-connect", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-solana", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-solana-core", "npm:0.11.0"]\ ],\ "linkType": "HARD"\ }]\ @@ -2268,11 +2301,11 @@ const RAW_RUNTIME_STATE = ["@coral-xyz/anchor", "npm:0.30.1"],\ ["@solana/web3.js", "npm:1.95.3"],\ ["@types/node", "npm:20.16.10"],\ - ["@wormhole-foundation/sdk-base", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-definitions", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-solana", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-solana-tokenbridge", "npm:0.10.9"],\ - ["@xlabs/solana-price-oracle-sdk", "npm:0.0.7::__archiveUrl=https%3A%2F%2Fnpm.pkg.github.com%2Fdownload%2F%40xlabs%2Fsolana-price-oracle-sdk%2F0.0.7%2F50706fa313c5a6f20564c024a5d7aef22ce95fc3"],\ + ["@wormhole-foundation/sdk-base", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-definitions", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-solana", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-solana-tokenbridge", "npm:0.11.0"],\ + ["@xlabs/solana-price-oracle-sdk", "link:./lib/../../relayer-infra-contracts/src/solana/::locator=%40xlabs-xyz%2Fsolana-arbitrary-token-transfers%40workspace%3Asdk%2Fsolana"],\ ["borsh", "npm:2.0.0"],\ ["tsup", "virtual:056deaaa1268de825ebb7f2126e3a2787838e2876e69eb46bc3ce4857072f92cede74aabe3915aa2d505c2a087a7d59d9170f4e7cc6428f30bd09123b7267c8f#npm:8.3.0"],\ ["tsx", "npm:4.19.1"],\ @@ -2282,15 +2315,13 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@xlabs/solana-price-oracle-sdk", [\ - ["npm:0.0.7::__archiveUrl=https%3A%2F%2Fnpm.pkg.github.com%2Fdownload%2F%40xlabs%2Fsolana-price-oracle-sdk%2F0.0.7%2F50706fa313c5a6f20564c024a5d7aef22ce95fc3", {\ - "packageLocation": "./.yarn/cache/@xlabs-solana-price-oracle-sdk-npm-0.0.7-74d09b9114-087932c718.zip/node_modules/@xlabs/solana-price-oracle-sdk/",\ + ["link:./lib/../../relayer-infra-contracts/src/solana/::locator=%40xlabs-xyz%2Fsolana-arbitrary-token-transfers%40workspace%3Asdk%2Fsolana", {\ + "packageLocation": "./sdk/relayer-infra-contracts/src/solana/",\ "packageDependencies": [\ - ["@xlabs/solana-price-oracle-sdk", "npm:0.0.7::__archiveUrl=https%3A%2F%2Fnpm.pkg.github.com%2Fdownload%2F%40xlabs%2Fsolana-price-oracle-sdk%2F0.0.7%2F50706fa313c5a6f20564c024a5d7aef22ce95fc3"],\ - ["@coral-xyz/anchor", "npm:0.30.1"],\ - ["@solana/web3.js", "npm:1.95.3"],\ - ["@wormhole-foundation/sdk-base", "npm:0.10.5"]\ + ["@xlabs/solana-price-oracle-sdk", "link:./lib/../../relayer-infra-contracts/src/solana/::locator=%40xlabs-xyz%2Fsolana-arbitrary-token-transfers%40workspace%3Asdk%2Fsolana"]\ ],\ - "linkType": "HARD"\ + "linkType": "SOFT",\ + "discardFromLookup": true\ }]\ ]],\ ["@yarnpkg/types", [\ @@ -5770,10 +5801,10 @@ const RAW_RUNTIME_STATE = ["@solana/web3.js", "npm:1.95.3"],\ ["@types/chai", "npm:4.3.19"],\ ["@types/mocha", "npm:8.2.3"],\ - ["@wormhole-foundation/sdk-base", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-definitions", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-solana-core", "npm:0.10.9"],\ - ["@wormhole-foundation/sdk-solana-tokenbridge", "npm:0.10.9"],\ + ["@wormhole-foundation/sdk-base", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-definitions", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-solana-core", "npm:0.11.0"],\ + ["@wormhole-foundation/sdk-solana-tokenbridge", "npm:0.11.0"],\ ["@xlabs-xyz/solana-arbitrary-token-transfers", "workspace:sdk/solana"],\ ["chai", "npm:5.1.1"],\ ["mocha", "npm:8.4.0"],\ diff --git a/.vscode/settings.json b/.vscode/settings.json index 04194e39..a5371817 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,7 @@ }, "prettier.prettierPath": ".yarn/sdks/prettier/index.cjs", "typescript.tsdk": ".yarn/sdks/typescript/lib", + "rust-analyzer.cargo.features": ["idl-build"], + "rust-analyzer.check.features": ["idl-build"], "typescript.enablePromptUseWorkspaceTsdk": true } diff --git a/Anchor.toml b/Anchor.toml index e992b138..03d71278 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -14,9 +14,9 @@ skip-lint = true [test] upgradeable = true -[[test.genesis]] -address = "ATqjh2vkjogyVUUNmXQssQZNSFGgSA7Tm6P1UzEUg85s" -program = "target/sbf-solana-solana/release/solana_price_oracle.so" +#[[test.genesis]] +#address = "CefQJaxQTV28gCf4MMd1PgDHgCcRmuEHZgXZwjJReUY3" +#program = "../relayer-infra-contracts/src/solana/target/sbf-solana-solana/release/solana_price_oracle.so" # [[test.genesis]] # address = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" # Mainnet in lib.rs diff --git a/Cargo.lock b/Cargo.lock index dfb18905..1fba7171 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1896,10 +1896,15 @@ dependencies = [ [[package]] name = "solana-price-oracle" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anchor-lang", + "anyhow", + "bs58 0.5.1", "cfg-if", + "ed25519-dalek", + "serde", + "serde_json", ] [[package]] @@ -2382,7 +2387,12 @@ version = "3.0.0" dependencies = [ "anchor-lang", "anchor-spl", + "anyhow", + "bs58 0.5.1", "cfg-if", + "ed25519-dalek", + "serde", + "serde_json", "solana-price-oracle", "wormhole-anchor-sdk", "wormhole-io", diff --git a/sdk/solana/package.json b/sdk/solana/package.json index 091c7a8d..e4ef0d1b 100644 --- a/sdk/solana/package.json +++ b/sdk/solana/package.json @@ -24,11 +24,11 @@ "dependencies": { "@coral-xyz/anchor": "^0.30.1", "@solana/web3.js": "^1.95.3", - "@wormhole-foundation/sdk-base": "^0.10.9", - "@wormhole-foundation/sdk-definitions": "^0.10.9", - "@wormhole-foundation/sdk-solana": "^0.10.9", - "@wormhole-foundation/sdk-solana-tokenbridge": "^0.10.9", - "@xlabs/solana-price-oracle-sdk": "^0.0.7", + "@wormhole-foundation/sdk-base": "^0.11", + "@wormhole-foundation/sdk-definitions": "^0.11", + "@wormhole-foundation/sdk-solana": "^0.11", + "@wormhole-foundation/sdk-solana-tokenbridge": "^0.11", + "@xlabs/solana-price-oracle-sdk": "link:./lib/../../relayer-infra-contracts/src/solana/", "borsh": "^2.0.0" }, "devDependencies": { diff --git a/sdk/solana/tbrv3/bpf-loader-upgradeable.ts b/sdk/solana/tbrv3/bpf-loader-upgradeable.ts index 2045ac40..1f7fa975 100644 --- a/sdk/solana/tbrv3/bpf-loader-upgradeable.ts +++ b/sdk/solana/tbrv3/bpf-loader-upgradeable.ts @@ -1,11 +1,5 @@ import anchor from '@coral-xyz/anchor'; -import { - Cluster, - clusterApiUrl, - Connection, - PublicKey, - TransactionInstruction, -} from '@solana/web3.js'; +import { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js'; import { CustomConversion, Layout, layout, Network } from '@wormhole-foundation/sdk-base'; //import { programDataLayout } from '@wormhole-foundation/sdk-solana/utils/utils/'; import { throwError } from 'common-arbitrary-token-transfer'; diff --git a/sdk/solana/tbrv3/idl/token_bridge_relayer.ts b/sdk/solana/tbrv3/idl/token_bridge_relayer.ts index 86c5e708..dbbf9a40 100644 --- a/sdk/solana/tbrv3/idl/token_bridge_relayer.ts +++ b/sdk/solana/tbrv3/idl/token_bridge_relayer.ts @@ -5,7 +5,7 @@ * IDL can be found at `target/idl/token_bridge_relayer.json`. */ export type TokenBridgeRelayer = { - "address": "7TLiBkpDGshV4o3jmacTCx93CLkmo3VjZ111AsijN9f8", + "address": "46kv4wCpfEtLsHPDh4zm7jJb2pVdvke8Pj2ABYYJotFD", "metadata": { "name": "tokenBridgeRelayer", "version": "3.0.0", @@ -401,11 +401,11 @@ export type TokenBridgeRelayer = { }, { "name": "wormholeProgram", - "address": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + "address": "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5" }, { "name": "tokenBridgeProgram", - "address": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb" + "address": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe" }, { "name": "rent", @@ -589,38 +589,38 @@ export type TokenBridgeRelayer = { { "kind": "const", "value": [ - 95, - 229, - 130, - 69, 46, - 141, - 178, - 231, - 56, - 213, + 12, + 158, + 160, + 36, + 68, 199, - 161, - 79, - 236, - 191, - 130, - 165, - 181, - 246, - 134, - 44, - 135, - 169, - 19, - 212, - 103, - 182, - 152, - 69, - 169, - 9, - 75 + 53, + 193, + 188, + 121, + 0, + 45, + 72, + 226, + 163, + 188, + 92, + 29, + 151, + 151, + 123, + 73, + 1, + 120, + 85, + 125, + 88, + 159, + 229, + 38, + 196 ] } ], @@ -1300,11 +1300,11 @@ export type TokenBridgeRelayer = { }, { "name": "tokenBridgeProgram", - "address": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb" + "address": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe" }, { "name": "wormholeProgram", - "address": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + "address": "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5" }, { "name": "clock", @@ -1637,16 +1637,16 @@ export type TokenBridgeRelayer = { ] }, { - "name": "evmPricesAccount", + "name": "evmPricesState", "discriminator": [ - 222, - 30, - 172, - 90, - 189, - 184, - 118, - 31 + 96, + 16, + 101, + 97, + 209, + 101, + 197, + 178 ] }, { @@ -1663,16 +1663,16 @@ export type TokenBridgeRelayer = { ] }, { - "name": "priceOracleConfigAccount", + "name": "priceOracleConfigState", "discriminator": [ - 192, - 215, - 139, - 0, - 191, - 210, - 185, - 218 + 86, + 37, + 173, + 69, + 170, + 230, + 127, + 150 ] }, { @@ -1848,13 +1848,20 @@ export type TokenBridgeRelayer = { } }, { - "name": "evmPricesAccount", + "name": "evmPricesState", "docs": [ "EVM chains prices." ], "type": { "kind": "struct", "fields": [ + { + "name": "chainId", + "docs": [ + "The chain that will be read or updated is identified by this field." + ], + "type": "u16" + }, { "name": "gasPrice", "docs": [ @@ -1904,7 +1911,7 @@ export type TokenBridgeRelayer = { } }, { - "name": "priceOracleConfigAccount", + "name": "priceOracleConfigState", "docs": [ "The program's main account." ], @@ -1918,20 +1925,6 @@ export type TokenBridgeRelayer = { ], "type": "pubkey" }, - { - "name": "admin", - "docs": [ - "Program's admin. Can be used to update the prices or appoint a new assistant." - ], - "type": "pubkey" - }, - { - "name": "assistant", - "docs": [ - "Program's assistant. Can be used to update the prices." - ], - "type": "pubkey" - }, { "name": "pendingOwner", "docs": [ diff --git a/sdk/solana/tbrv3/token-bridge-relayer.ts b/sdk/solana/tbrv3/token-bridge-relayer.ts index d82f9557..00c41463 100644 --- a/sdk/solana/tbrv3/token-bridge-relayer.ts +++ b/sdk/solana/tbrv3/token-bridge-relayer.ts @@ -9,6 +9,7 @@ import { clusterApiUrl, Cluster, LAMPORTS_PER_SOL, + Keypair, } from '@solana/web3.js'; import * as borsh from 'borsh'; import { @@ -17,7 +18,6 @@ import { encoding, contracts, Network, - chain, chainIdToChain, } from '@wormhole-foundation/sdk-base'; import { UniversalAddress } from '@wormhole-foundation/sdk-definitions'; @@ -27,17 +27,19 @@ import { getCompleteTransferNativeWithPayloadCpiAccounts, getCompleteTransferWrappedWithPayloadCpiAccounts, } from '@wormhole-foundation/sdk-solana-tokenbridge'; -import { SolanaPriceOracleClient } from '@xlabs/solana-price-oracle-sdk'; +import { SolanaPriceOracle } from '@xlabs/solana-price-oracle-sdk'; +import { deserializeTbrV3Message, VaaMessage, throwError } from 'common-arbitrary-token-transfer'; +import { BpfLoaderUpgradeableProgram } from './bpf-loader-upgradeable.js'; import { TokenBridgeRelayer } from './idl/token_bridge_relayer.js'; import IDL from '../../../target/idl/token_bridge_relayer.json' with { type: 'json' }; -import { deserializeTbrV3Message, VaaMessage, throwError } from 'common-arbitrary-token-transfer'; -import { BpfLoaderUpgradeableProgram } from './bpf-loader-upgradeable.js'; +import networkConfig from '../../../solana/programs/token-bridge-relayer/network.json'; +import testProgramKeypair from '../../../solana/programs/token-bridge-relayer/test-program-keypair.json'; // Export IDL export * from './idl/token_bridge_relayer.js'; export const idl = IDL; -export { SolanaPriceOracleClient } from '@xlabs/solana-price-oracle-sdk'; +export { SolanaPriceOracle } from '@xlabs/solana-price-oracle-sdk'; export type { VaaMessage } from 'common-arbitrary-token-transfer'; export interface WormholeAddress { @@ -71,6 +73,8 @@ export type PeerAccount = anchor.IdlAccounts['peerState']; export type SignerSequenceAccount = anchor.IdlAccounts['signerSequenceState']; export type AuthBadgeAccount = anchor.IdlAccounts['authBadgeState']; +export type NetworkOrLocal = Network | 'Localnet'; + /** * Transforms a `UniversalAddress` into an array of numbers `number[]`. */ @@ -78,24 +82,28 @@ export const uaToArray = (ua: UniversalAddress): number[] => Array.from(ua.toUin export class SolanaTokenBridgeRelayer { public readonly program: anchor.Program; - private readonly priceOracleClient: SolanaPriceOracleClient; + private readonly priceOracleClient: SolanaPriceOracle; private readonly wormholeProgramId: PublicKey; private readonly tokenBridgeProgramId: PublicKey; /** * Creates a SolanaTokenBridgeRelayer instance. - * When env.address is not provided, the IDL value is used. - * When env.network is not provided, the network is detected - * using the provider url, which works for official solana nodes only. */ - constructor(provider: anchor.Provider, env: { address?: string, network?: Network } = {}) { - const network = env.network ?? networkFromConnection(provider.connection); - myDebug('Network detected to be:', network); - - this.program = new Program(patchAddress(IDL, env.address), provider); - this.priceOracleClient = new SolanaPriceOracleClient(provider.connection); - this.wormholeProgramId = new PublicKey(contracts.coreBridge(network, 'Solana')); - this.tokenBridgeProgramId = new PublicKey(contracts.tokenBridge(network, 'Solana')); + constructor(provider: anchor.Provider, network: NetworkOrLocal, programId: PublicKey) { + const wormholeNetwork = network === 'Localnet' ? 'Mainnet' : network; + + this.program = new Program(patchAddress(IDL, programId), provider); + this.priceOracleClient = new SolanaPriceOracle(provider.connection); + this.wormholeProgramId = new PublicKey(contracts.coreBridge(wormholeNetwork, 'Solana')); + this.tokenBridgeProgramId = new PublicKey(contracts.tokenBridge(wormholeNetwork, 'Solana')); + } + + static async create(provider: anchor.Provider): Promise { + const network = await networkFromConnection(provider.connection); + const programId = await programIdFromNetwork(network); + myDebug('Detected environment', { network, programId }); + + return new SolanaTokenBridgeRelayer(provider, network, programId); } get connection(): Connection { @@ -260,11 +268,13 @@ export class SolanaTokenBridgeRelayer { const program = new BpfLoaderUpgradeableProgram(this.program.programId, this.connection); const deployer = (await program.getdata()).upgradeAuthority ?? throwError('The program must be upgradeable'); + console.log('program data address', program.dataAddress); return await this.program.methods .initialize(feeRecipient, admins) - .accounts({ + .accountsPartial({ deployer, + programData: program.dataAddress, owner, }) .remainingAccounts(authBadges) @@ -525,8 +535,8 @@ export class SolanaTokenBridgeRelayer { userTokenAccount, temporaryAccount: pda.temporary(this.program.programId, mint), feeRecipient, - oracleConfig: this.priceOracleClient.address.config(), - oracleEvmPrices: this.priceOracleClient.address.evmPrices(recipient.chain), + oracleConfig: this.priceOracleClient.account.config().address, + oracleEvmPrices: this.priceOracleClient.account.evmPrices(recipient.chain).address, ...tokenBridgeAccounts, wormholeMessage: pda.wormholeMessage(this.program.programId, signer, payerSequenceNumber), payerSequence: this.address.signerSequence(signer), @@ -582,8 +592,8 @@ export class SolanaTokenBridgeRelayer { userTokenAccount, temporaryAccount: pda.temporary(this.program.programId, tokenBridgeAccounts.mint), feeRecipient, - oracleConfig: this.priceOracleClient.address.config(), - oracleEvmPrices: this.priceOracleClient.address.evmPrices(recipient.chain), + oracleConfig: this.priceOracleClient.account.config().address, + oracleEvmPrices: this.priceOracleClient.account.evmPrices(recipient.chain).address, ...tokenBridgeAccounts, wormholeMessage: pda.wormholeMessage(this.program.programId, signer, payerSequenceNumber), payerSequence: this.address.signerSequence(signer), @@ -638,10 +648,7 @@ export class SolanaTokenBridgeRelayer { myDebug('completeNativeTransfer:', accounts); - return this.program.methods - .completeTransfer() - .accountsPartial(accounts) - .instruction(); + return this.program.methods.completeTransfer().accountsPartial(accounts).instruction(); } /** @@ -677,10 +684,7 @@ export class SolanaTokenBridgeRelayer { myDebug('completeWrappedTransfer:', accounts); - return this.program.methods - .completeTransfer() - .accountsPartial(accounts) - .instruction(); + return this.program.methods.completeTransfer().accountsPartial(accounts).instruction(); } /* Queries */ @@ -699,8 +703,8 @@ export class SolanaTokenBridgeRelayer { .accountsStrict({ tbrConfig: this.address.config(), chainConfig: this.address.chainConfig(chain), - oracleConfig: this.priceOracleClient.address.config(), - oracleEvmPrices: this.priceOracleClient.address.evmPrices(chain), + oracleConfig: this.priceOracleClient.account.config().address, + oracleEvmPrices: this.priceOracleClient.account.evmPrices(chain).address, }) .rpc({ commitment: 'confirmed' }); const txResponse = await this.connection.getTransaction(tx, { @@ -967,23 +971,38 @@ function completeWrappedTokenBridgeAccounts(params: { /** * Detects the network from a Solana connection. */ -function networkFromConnection(connection: Connection): Network { - function clusterRpcEndpoint(cluster: Cluster) { - return new Connection(clusterApiUrl(cluster), 'singleGossip').rpcEndpoint; +async function networkFromConnection(connection: Connection): Promise { + function genesisHash(cluster: Cluster) { + return new Connection(clusterApiUrl(cluster), 'singleGossip').getGenesisHash(); } - const mainnet = clusterRpcEndpoint('mainnet-beta'); - const devnet = clusterRpcEndpoint('devnet'); - const testnet = clusterRpcEndpoint('testnet'); + const [mainnet, devnet, testnet] = await Promise.all([ + genesisHash('mainnet-beta'), + genesisHash('devnet'), + genesisHash('testnet'), + ]); - switch (connection.rpcEndpoint) { + switch (await connection.getGenesisHash()) { case mainnet: return 'Mainnet'; case devnet: return 'Devnet'; case testnet: return 'Testnet'; - default: // We consider that it is localnet, and use the mainnet values: - return 'Mainnet'; + default: + return 'Localnet'; + } +} + +async function programIdFromNetwork(network: NetworkOrLocal) { + switch (network) { + case 'Mainnet': + return new PublicKey(networkConfig.mainnet); + case 'Devnet': + return new PublicKey(networkConfig.devnet); + case 'Testnet': + return new PublicKey(networkConfig.testnet); + case 'Localnet': + return Keypair.fromSecretKey(Uint8Array.from(testProgramKeypair)).publicKey; } } @@ -994,18 +1013,18 @@ function myDebug(message?: any, ...optionalParams: any[]) { /** * Crappy fix for allowing to override address to support multiple environments */ -function patchAddress(idl: any, address?: string) { +function patchAddress(idl: any, address?: PublicKey) { if (address) { - return { ...idl, address }; + return { ...idl, address: address.toString() }; } return idl; } -function bnToBigint(n: anchor.BN): bigint { - return BigInt(n.toString()); +export function bnToBigint(n: anchor.BN): bigint { + return BigInt(`0x${n.toString('hex')}`); } -function bigintToBn(n: bigint): anchor.BN { - return new anchor.BN(n.toString()); +export function bigintToBn(n: bigint): anchor.BN { + return new anchor.BN(`${n.toString(16)}`, 'hex'); } diff --git a/solana/package.json b/solana/package.json index e4ce724b..fcb8195e 100644 --- a/solana/package.json +++ b/solana/package.json @@ -17,10 +17,10 @@ "@solana/web3.js": "^1.95.3", "@types/chai": "^4.3.19", "@types/mocha": "8.*", - "@wormhole-foundation/sdk-base": "^0.10.9", - "@wormhole-foundation/sdk-definitions": "^0.10.9", - "@wormhole-foundation/sdk-solana-core": "^0.10.9", - "@wormhole-foundation/sdk-solana-tokenbridge": "^0.10.9", + "@wormhole-foundation/sdk-base": "^0.11", + "@wormhole-foundation/sdk-definitions": "^0.11", + "@wormhole-foundation/sdk-solana-core": "^0.11", + "@wormhole-foundation/sdk-solana-tokenbridge": "^0.11", "@xlabs-xyz/solana-arbitrary-token-transfers": "workspace:^", "chai": "^5.1.1", "mocha": "8.*", diff --git a/solana/programs/token-bridge-relayer/Cargo.toml b/solana/programs/token-bridge-relayer/Cargo.toml index 2fadce00..628d19c3 100644 --- a/solana/programs/token-bridge-relayer/Cargo.toml +++ b/solana/programs/token-bridge-relayer/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib", "lib"] name = "token_bridge_relayer" [features] -default = ["solana-price-oracle/cpi", "localnet"] +default = ["solana-price-oracle/cpi"] cpi = ["no-entrypoint"] no-entrypoint = [] no-idl = [] @@ -19,15 +19,16 @@ idl-build = [ "anchor-spl/idl-build", "wormhole-anchor-sdk/idl-build", ] - -# Environments +# Networks: mainnet = ["solana-price-oracle/mainnet", "wormhole-anchor-sdk/mainnet"] solana-devnet = [ "solana-price-oracle/solana-devnet", "wormhole-anchor-sdk/solana-devnet", ] -tilt-devnet = ["solana-price-oracle/tilt-devnet"] -localnet = ["solana-price-oracle/mainnet", "wormhole-anchor-sdk/mainnet"] +tilt-devnet = [ + "solana-price-oracle/tilt-devnet", + "wormhole-anchor-sdk/tilt-devnet", +] [dependencies] cfg-if = "1" @@ -36,7 +37,6 @@ anchor-lang = { version = "0.30.1", git = "https://github.com/coral-xyz/anchor/" ] } anchor-spl = { version = "0.30.1", git = "https://github.com/coral-xyz/anchor/", rev = "8d52c1c" } -#solana-price-oracle = { git = "ssh://git@github.com/XLabs/relayer-infra-contracts/", branch = "main" } solana-price-oracle = { path = "../../../lib/relayer-infra-contracts/src/solana/programs/price-oracle" } #wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding.git", rev = "1acd10e3cbeea0df06976b606bd24da2e8e849e1", features = ["token-bridge"] } @@ -48,3 +48,10 @@ wormhole-anchor-sdk = { git = "https://github.com/real-felix/wormhole-scaffoldin #wormhole-solana-utils = { version = "0.3.0-alpha.1", features = ["anchor"]} wormhole-io = "0.1" + +[build-dependencies] +serde = "1" +serde_json = "1" +anyhow = "1" +ed25519-dalek = "1.0.1" # Same as in the Solana dependencies +bs58 = "0.5.1" diff --git a/solana/programs/token-bridge-relayer/build.rs b/solana/programs/token-bridge-relayer/build.rs new file mode 100644 index 00000000..4b16cb41 --- /dev/null +++ b/solana/programs/token-bridge-relayer/build.rs @@ -0,0 +1,110 @@ +use anyhow::{Context, Result}; +use serde::Deserialize; +use std::fs; + +#[rustfmt::skip] +#[cfg(any( + all(feature = "mainnet", any(feature = "solana-devnet", feature = "tilt-devnet")), + all(feature = "solana-devnet", any(feature = "mainnet", feature = "tilt-devnet")), + all(feature = "tilt-devnet", any(feature = "mainnet", feature = "solana-devnet")), +))] +compile_error!("Network features are mutually exclusive: 'mainnet', 'solana-devnet', 'tilt-devnet'."); + +#[cfg(not(any( + feature = "mainnet", + feature = "solana-devnet", + feature = "tilt-devnet" +)))] +const TEST_KEYPAIR_PATH: &str = "test-program-keypair.json"; + +// Example custom build script. +fn main() -> Result<()> { + // Tell Cargo that if the JSON file changes, or the env variable, to rerun this build script: + println!("cargo:rerun-if-changed=network.json"); + + // Generate the id.rs file: + let network = Network::deserialize("network.json")?; + let addresses = network.value()?; + + fs::write( + "src/id.rs", + format!( + "anchor_lang::prelude::declare_id!({:?});\n\ + pub const WORMHOLE_MINT_AUTHORITY: anchor_lang::prelude::Pubkey =\n anchor_lang::pubkey!({:?});\n", + addresses.program_id, addresses.wormhole_mint_authority, + ), + ) + .context("could not write the file: id.rs")?; + + Ok(()) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct Network { + #[cfg(any( + feature = "mainnet", + not(any(feature = "solana-devnet", feature = "tilt-devnet")) + ))] + mainnet: NetworkAddresses, + #[cfg(feature = "solana-devnet")] + devnet: NetworkAddresses, + #[cfg(feature = "tilt-devnet")] + testnet: NetworkAddresses, +} + +#[derive(Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +struct NetworkAddresses { + program_id: String, + wormhole_mint_authority: String, +} + +impl Network { + fn deserialize(path: &str) -> Result { + let file = fs::read_to_string(path).context(format!( + "Failed to read the file with the network config: {path}" + ))?; + let content = serde_json::from_str(&file) + .context(format!("Failed to deserialize the file: {path}"))?; + + Ok(content) + } + + #[cfg(feature = "mainnet")] + fn value(&self) -> Result { + Ok(self.mainnet.clone()) + } + + #[cfg(feature = "solana-devnet")] + fn value(&self) -> Result { + Ok(self.devnet.clone()) + } + + #[cfg(feature = "tilt-devnet")] + fn value(&self) -> Result { + Ok(self.testnet.clone()) + } + + #[cfg(not(any( + feature = "mainnet", + feature = "solana-devnet", + feature = "tilt-devnet" + )))] + fn value(&self) -> Result { + let file = fs::read_to_string(TEST_KEYPAIR_PATH).context(format!( + "Failed to read the file with the test program keypair: {TEST_KEYPAIR_PATH}" + ))?; + let content: Vec = serde_json::from_str(&file).context(format!( + "Failed to deserialize the file: {TEST_KEYPAIR_PATH}" + ))?; + assert_eq!(content.len(), 64, "The keypair file should have 64 bytes"); + let keypair = ed25519_dalek::Keypair::from_bytes(&content) + .context(format!("Invalid keypair in the file: {TEST_KEYPAIR_PATH}"))?; + + Ok(NetworkAddresses { + program_id: bs58::encode(keypair.public.as_bytes()).into_string(), + ..self.mainnet.clone() + }) + } +} diff --git a/solana/programs/token-bridge-relayer/network.json b/solana/programs/token-bridge-relayer/network.json new file mode 100644 index 00000000..8c4bf8c9 --- /dev/null +++ b/solana/programs/token-bridge-relayer/network.json @@ -0,0 +1,14 @@ +{ + "mainnet": { + "programId": "AtTrxsPbTfBhC9uwwJGJbkFMux78t5EWTAXAbwUW8yC7", + "wormholeMintAuthority": "BCD75RNBHrJJpW4dXVagL5mPjzRLnVZq4YirJdjEYMV7" + }, + "devnet": { + "programId": "ATT7enfWTMV4dDTe2NQ2yBaTByuXXwrYRznsioQEUW6r", + "wormholeMintAuthority": "rRsXLHe7sBHdyKU3KY3wbcgWvoT1Ntqudf6e9PKusgb" + }, + "testnet": { + "programId": "46kv4wCpfEtLsHPDh4zm7jJb2pVdvke8Pj2ABYYJotFD", + "wormholeMintAuthority": "8P2wAnHr2t4pAVEyJftzz7k6wuCE7aP1VugNwehzCJJY" + } +} diff --git a/solana/programs/token-bridge-relayer/src/lib.rs b/solana/programs/token-bridge-relayer/src/lib.rs index fdc8a1df..6f88cd1f 100644 --- a/solana/programs/token-bridge-relayer/src/lib.rs +++ b/solana/programs/token-bridge-relayer/src/lib.rs @@ -1,4 +1,5 @@ mod error; +mod id; mod message; mod processor; mod state; @@ -7,21 +8,7 @@ mod utils; use anchor_lang::prelude::*; use processor::*; -cfg_if::cfg_if! { - if #[cfg(feature = "mainnet")] { - declare_id!("AtTrxsPbTfBhC9uwwJGJbkFMux78t5EWTAXAbwUW8yC7"); - const WORMHOLE_MINT_AUTHORITY: Pubkey = anchor_lang::pubkey!("BCD75RNBHrJJpW4dXVagL5mPjzRLnVZq4YirJdjEYMV7"); - } else if #[cfg(feature = "solana-devnet")] { - declare_id!("ATT7enfWTMV4dDTe2NQ2yBaTByuXXwrYRznsioQEUW6r"); - const WORMHOLE_MINT_AUTHORITY: Pubkey = anchor_lang::pubkey!("rRsXLHe7sBHdyKU3KY3wbcgWvoT1Ntqudf6e9PKusgb"); - } else if #[cfg(feature = "tilt-devnet")] { - declare_id!("46kv4wCpfEtLsHPDh4zm7jJb2pVdvke8Pj2ABYYJotFD"); - const WORMHOLE_MINT_AUTHORITY: Pubkey = anchor_lang::pubkey!("8P2wAnHr2t4pAVEyJftzz7k6wuCE7aP1VugNwehzCJJY"); - } else if #[cfg(feature = "localnet")] { - declare_id!("7TLiBkpDGshV4o3jmacTCx93CLkmo3VjZ111AsijN9f8"); - const WORMHOLE_MINT_AUTHORITY: Pubkey = anchor_lang::pubkey!("BCD75RNBHrJJpW4dXVagL5mPjzRLnVZq4YirJdjEYMV7"); - } -} +pub use id::ID; pub mod constant { use anchor_lang::prelude::*; diff --git a/solana/programs/token-bridge-relayer/src/processor/inbound.rs b/solana/programs/token-bridge-relayer/src/processor/inbound.rs index 1d28def2..c819f477 100644 --- a/solana/programs/token-bridge-relayer/src/processor/inbound.rs +++ b/solana/programs/token-bridge-relayer/src/processor/inbound.rs @@ -9,7 +9,7 @@ use anchor_lang::{prelude::*, system_program}; use anchor_spl::token::{spl_token::native_mint, Mint, Token, TokenAccount}; use wormhole_anchor_sdk::{ token_bridge::{self, program::TokenBridge}, - wormhole::{self, program::Wormhole}, + wormhole::program::Wormhole, }; #[derive(Accounts)] diff --git a/solana/programs/token-bridge-relayer/src/processor/outbound.rs b/solana/programs/token-bridge-relayer/src/processor/outbound.rs index 4f62e1bd..24b073b6 100644 --- a/solana/programs/token-bridge-relayer/src/processor/outbound.rs +++ b/solana/programs/token-bridge-relayer/src/processor/outbound.rs @@ -8,7 +8,7 @@ use crate::{ use anchor_lang::prelude::*; use anchor_spl::token::{Mint, Token, TokenAccount}; use solana_price_oracle::{ - state::{EvmPricesAccount, PriceOracleConfigAccount}, + state::{EvmPricesState, PriceOracleConfigState}, PriceOracle, }; use wormhole_anchor_sdk::{ @@ -75,14 +75,14 @@ pub struct OutboundTransfer<'info> { #[account(mut)] pub fee_recipient: UncheckedAccount<'info>, - pub oracle_config: Box>, + pub oracle_config: Box>, #[account( - seeds = [EvmPricesAccount::SEED_PREFIX, chain_config.chain_id.to_be_bytes().as_ref()], + seeds = [EvmPricesState::SEED_PREFIX, chain_config.chain_id.to_be_bytes().as_ref()], seeds::program = PriceOracle::id(), bump, )] - pub oracle_evm_prices: Box>, + pub oracle_evm_prices: Box>, /// CHECK: Token Bridge config. Read-only. pub token_bridge_config: UncheckedAccount<'info>, diff --git a/solana/programs/token-bridge-relayer/src/processor/queries.rs b/solana/programs/token-bridge-relayer/src/processor/queries.rs index c1136f42..1c5c69de 100644 --- a/solana/programs/token-bridge-relayer/src/processor/queries.rs +++ b/solana/programs/token-bridge-relayer/src/processor/queries.rs @@ -4,7 +4,7 @@ use crate::{ }; use anchor_lang::prelude::*; use solana_price_oracle::{ - state::{EvmPricesAccount, PriceOracleConfigAccount}, + state::{EvmPricesState, PriceOracleConfigState}, PriceOracle, }; @@ -17,14 +17,14 @@ pub struct QuoteQuery<'info> { /// canonical peer. pub chain_config: Account<'info, ChainConfigState>, - pub oracle_config: Account<'info, PriceOracleConfigAccount>, + pub oracle_config: Account<'info, PriceOracleConfigState>, #[account( - seeds = [EvmPricesAccount::SEED_PREFIX, chain_config.chain_id.to_be_bytes().as_ref()], + seeds = [EvmPricesState::SEED_PREFIX, chain_config.chain_id.to_be_bytes().as_ref()], seeds::program = PriceOracle::id(), bump, )] - pub oracle_evm_prices: Account<'info, EvmPricesAccount>, + pub oracle_evm_prices: Account<'info, EvmPricesState>, } pub fn relaying_fee(ctx: Context, dropoff_amount: u32) -> Result { diff --git a/solana/programs/token-bridge-relayer/src/utils.rs b/solana/programs/token-bridge-relayer/src/utils.rs index 0611121d..97ffcd98 100644 --- a/solana/programs/token-bridge-relayer/src/utils.rs +++ b/solana/programs/token-bridge-relayer/src/utils.rs @@ -6,7 +6,7 @@ use anchor_lang::{ prelude::*, solana_program::{native_token::LAMPORTS_PER_SOL, program_option::COption}, }; -use solana_price_oracle::state::{EvmPricesAccount, PriceOracleConfigAccount}; +use solana_price_oracle::state::{EvmPricesState, PriceOracleConfigState}; const MWEI_PER_MICRO_ETH: u64 = 1_000_000; const MWEI_PER_ETH: u128 = 1_000_000_000_000; @@ -26,8 +26,8 @@ const MWEI_PER_ETH: u128 = 1_000_000_000_000; pub fn calculate_total_fee( config: &TbrConfigState, chain_config: &ChainConfigState, - oracle_evm_prices: &EvmPricesAccount, - oracle_config: &PriceOracleConfigAccount, + oracle_evm_prices: &EvmPricesState, + oracle_config: &PriceOracleConfigState, dropoff_amount_micro: u32, ) -> Result { check_prices_are_set(oracle_evm_prices)?; @@ -72,7 +72,7 @@ pub fn calculate_total_fee( /// This is a basic security against a wrong manip, to be sure that the prices /// have been set correctly. -fn check_prices_are_set(evm_prices: &EvmPricesAccount) -> Result<()> { +fn check_prices_are_set(evm_prices: &EvmPricesState) -> Result<()> { require_neq!( evm_prices.gas_price, 0, @@ -94,7 +94,7 @@ fn check_prices_are_set(evm_prices: &EvmPricesAccount) -> Result<()> { pub fn create_native_check( mint_authority: COption, ) -> impl Fn(bool) -> TokenBridgeRelayerResult { - let is_wormhole_mint = mint_authority == COption::Some(crate::WORMHOLE_MINT_AUTHORITY); + let is_wormhole_mint = mint_authority == COption::Some(crate::id::WORMHOLE_MINT_AUTHORITY); return move |expected_native| { // Valid values: either: diff --git a/solana/tests/program.json b/solana/programs/token-bridge-relayer/test-program-keypair.json similarity index 100% rename from solana/tests/program.json rename to solana/programs/token-bridge-relayer/test-program-keypair.json diff --git a/solana/tests/token-bridge-relayer-tests.ts b/solana/tests/token-bridge-relayer-tests.ts index 8ad4867e..63b5aa1b 100644 --- a/solana/tests/token-bridge-relayer-tests.ts +++ b/solana/tests/token-bridge-relayer-tests.ts @@ -7,11 +7,10 @@ import { newProvider, requestAirdrop, deployProgram, - putProgramKeyBackInIdl, keypairFromFile, } from './utils/helpers.js'; import { TbrWrapper } from './utils/client-wrapper.js'; -import { SolanaPriceOracleClient, uaToArray } from '@xlabs-xyz/solana-arbitrary-token-transfers'; +import { SolanaPriceOracle, uaToArray } from '@xlabs-xyz/solana-arbitrary-token-transfers'; import { expect } from 'chai'; const ETHEREUM = 'Ethereum'; @@ -19,6 +18,8 @@ const ETHEREUM_ID = chainToChainId(ETHEREUM); const OASIS = 'Oasis'; const OASIS_ID = chainToChainId(OASIS); +const authorityKeypairPath = './target/deploy/token_bridge_relayer-keypair.json'; + describe('Token Bridge Relayer Program', () => { const clients = (['owner', 'owner', 'admin', 'admin', 'admin', 'regular'] as const).map( (typeAccount) => new TbrWrapper(newProvider(), typeAccount), @@ -31,9 +32,7 @@ describe('Token Bridge Relayer Program', () => { adminClient3, unauthorizedClient, ] = clients; - - const oracleOwner = newProvider(); - const oracleOwnerClient = new SolanaPriceOracleClient(oracleOwner.connection); + let upgradeAuthorityClient: TbrWrapper; const wormholeCoreOwner = newProvider(); //const wormholeCoreClient = new WormholeCoreWrapper(wormholeCoreOwner); @@ -57,50 +56,64 @@ describe('Token Bridge Relayer Program', () => { before(async () => { await Promise.all(clients.map((client) => requestAirdrop(client.provider))); + upgradeAuthorityClient = new TbrWrapper( + newProvider(await keypairFromFile(authorityKeypairPath)), + 'owner', + ); // Program Deployment // ============ - const authorityKeypairPath = './target/deploy/token_bridge_relayer-keypair.json'; - const authorityProvider = newProvider(await keypairFromFile(authorityKeypairPath)); - await requestAirdrop(authorityProvider); - deployProgram( - './solana/tests/program.json', - authorityKeypairPath, - './target/sbf-solana-solana/release/token_bridge_relayer.so', - ); - await putProgramKeyBackInIdl('7TLiBkpDGshV4o3jmacTCx93CLkmo3VjZ111AsijN9f8'); + await Promise.all([ + // Token Bridge Relayer + deployProgram( + './solana/programs/token-bridge-relayer/test-program-keypair.json', + authorityKeypairPath, + './target/sbf-solana-solana/release/token_bridge_relayer.so', + ), + // Price Oracle + deployProgram( + './lib/relayer-infra-contracts/src/solana/programs/price-oracle/test-program-keypair.json', + authorityKeypairPath, + './lib/relayer-infra-contracts/src/solana/target/sbf-solana-solana/release/solana_price_oracle.so', + ), + ]); // Oracle Setup // ============ - await requestAirdrop(oracleOwner); - - await oracleOwner.sendAndConfirm( + const oracleAuthorityProvider = newProvider(await keypairFromFile(authorityKeypairPath)); + const oracleAuthorityClient = new SolanaPriceOracle(oracleAuthorityProvider.connection); + await oracleAuthorityProvider.sendAndConfirm( new Transaction().add( - await oracleOwnerClient.initialize(oracleOwner.publicKey), - await oracleOwnerClient.registerEvmPrices(oracleOwner.publicKey, { + await oracleAuthorityClient.initialize(oracleAuthorityProvider.publicKey, [], []), + await oracleAuthorityClient.registerEvmPrices(oracleAuthorityProvider.publicKey, { chain: ETHEREUM, gasPrice: 2117, // 1 gas costs 2117 Mwei pricePerByte: 0, // ETH does not care about transaction size - gasTokenPrice: new anchor.BN(789_000_000), // ETH is at $789 + gasTokenPrice: 789_000_000n, // ETH is at $789 }), - await oracleOwnerClient.updateSolPrice(oracleOwner.publicKey, new anchor.BN(113_000_000)), // SOL is at $113 + await oracleAuthorityClient.updateSolPrice(oracleAuthorityProvider.publicKey, 113_000_000n), // SOL is at $113 ), ); // Wormhole Core Setup // =================== //await wormholeCoreClient.initialize(); + + //console.log('Now waiting for 40s'); + //setTimeout(() => {}, 40000); //Wait for 40 seconds + throw new Error('oops'); }); after(async () => { // Prevents the tests to be stuck, by closing the open channels. + clients.push(upgradeAuthorityClient); await Promise.all(clients.map((client) => client.close())); }); it('Is initialized!', async () => { - await TbrWrapper.initialize({ + await upgradeAuthorityClient.initialize({ feeRecipient, owner: ownerClient.publicKey, admins: [adminClient1.publicKey, adminClient2.publicKey], diff --git a/solana/tests/utils/client-wrapper.ts b/solana/tests/utils/client-wrapper.ts index cdc67c12..ad5a39e1 100644 --- a/solana/tests/utils/client-wrapper.ts +++ b/solana/tests/utils/client-wrapper.ts @@ -12,13 +12,12 @@ import { sendAndConfirmIxs, wormholeProgramId, tokenBridgeProgramId, - newProvider, - keypairFromFile, + keypairFromArray, } from './helpers.js'; import { SolanaWormholeCore } from '@wormhole-foundation/sdk-solana-core'; import { SolanaAutomaticTokenBridge } from '@wormhole-foundation/sdk-solana-tokenbridge'; -const LOCALNET_ADDRESS = '7TLiBkpDGshV4o3jmacTCx93CLkmo3VjZ111AsijN9f8'; +import testProgramKeypair from '../../programs/token-bridge-relayer/test-program-keypair.json'; export class TbrWrapper { readonly client: SolanaTokenBridgeRelayer; @@ -28,11 +27,15 @@ export class TbrWrapper { constructor(provider: AnchorProvider, accountType: 'owner' | 'admin' | 'regular') { this.provider = provider; - if (accountType === 'regular') { - this.client = new SolanaTokenBridgeRelayer(provider, { address: LOCALNET_ADDRESS }); - } else { - this.client = new SolanaTokenBridgeRelayer({ connection: provider.connection }, { address: LOCALNET_ADDRESS }); - } + const clientProvider = + accountType === 'regular' ? provider : { connection: provider.connection }; + + this.client = new SolanaTokenBridgeRelayer( + clientProvider, + 'Localnet', + keypairFromArray(testProgramKeypair).publicKey, + ); + this.logs = {}; this.logsSubscriptionId = provider.connection.onLogs( @@ -64,19 +67,12 @@ export class TbrWrapper { } } - static async initialize(args: { + async initialize(args: { owner: PublicKey; feeRecipient: PublicKey; admins: PublicKey[]; }): Promise { - const authorityProvider = newProvider( - await keypairFromFile('./target/deploy/token_bridge_relayer-keypair.json'), - ); - const client = new SolanaTokenBridgeRelayer(authorityProvider); - console.log('Authority Key --', authorityProvider.publicKey.toString()); - console.log('Program ID -----', client.program.programId.toString()); - - return sendAndConfirmIxs(authorityProvider, await client.initialize(args)); + return sendAndConfirmIxs(this.provider, await this.client.initialize(args)); } async submitOwnerTransferRequest(newOwner: PublicKey): Promise { diff --git a/solana/tests/utils/helpers.ts b/solana/tests/utils/helpers.ts index b96aa8da..62e8a54c 100644 --- a/solana/tests/utils/helpers.ts +++ b/solana/tests/utils/helpers.ts @@ -10,10 +10,16 @@ import { RpcResponseAndContext, SignatureResult, } from '@solana/web3.js'; -import { ChainConfigAccount } from '@xlabs-xyz/solana-arbitrary-token-transfers'; +import { + BpfLoaderUpgradeableProgram, + ChainConfigAccount, +} from '@xlabs-xyz/solana-arbitrary-token-transfers'; import { expect } from 'chai'; -import { execSync } from 'child_process'; import fs from 'fs/promises'; +import { promisify } from 'util'; +import { exec } from 'child_process'; + +const execAsync = promisify(exec); const LOCALHOST = 'http://localhost:8899'; export const wormholeProgramId = new PublicKey('worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth'); @@ -129,6 +135,10 @@ export async function keypairFromFile(path: string) { ); } +export function keypairFromArray(keypair: number[]) { + return Keypair.fromSecretKey(Uint8Array.from(keypair)); +} + /** * * @param programKeyPairPath The path to the JSON keypair. @@ -140,26 +150,19 @@ export async function deployProgram( authorityKeyPairPath: string, artifactPath: string, ) { - // deploy - execSync( - `solana --url localhost -k ${authorityKeyPairPath} program deploy ${artifactPath} --program-id ${programKeyPairPath}`, + // Deploy: + await execAsync( + `solana --url ${LOCALHOST} -k ${authorityKeyPairPath} program deploy ${artifactPath} --program-id ${programKeyPairPath}`, ); // Wait for deploy to be finalized. Don't remove. - const programPublicKey = await keypairFromFile(programKeyPairPath).then((kp) => kp.publicKey); + const programId = await keypairFromFile(programKeyPairPath).then((kp) => kp.publicKey); const connection = AnchorProvider.local().connection; + const bpfProgram = new BpfLoaderUpgradeableProgram(programId, connection); + const programDataAddress = bpfProgram.dataAddress; let programAccount = null; while (programAccount === null) { - programAccount = await connection.getAccountInfo(programPublicKey, 'finalized'); + programAccount = await connection.getAccountInfo(programDataAddress, 'finalized'); } -} - -export async function putProgramKeyBackInIdl(programId: string) { - const idlPath = './target/idl/token_bridge_relayer.json'; - const idlRaw = await fs.readFile(idlPath, 'utf-8'); - const idl = JSON.parse(idlRaw); - - idl.address = programId; - - await fs.writeFile(idlPath, JSON.stringify(idl, null, 2)); + console.log('Found programAccount:', { programDataAddress, programId, programAccount }); } diff --git a/solana/tsconfig.json b/solana/tsconfig.json index 100c6cba..7a1c674e 100644 --- a/solana/tsconfig.json +++ b/solana/tsconfig.json @@ -5,8 +5,6 @@ "moduleResolution": "node", "outDir": "ts-build" }, - "include": ["tests"], - "references": [ - { "path": "../sdk/solana/tsconfig.json" } - ] + "include": ["tests", "programs/token-bridge-relayer/*.json"], + "references": [{ "path": "../sdk/solana/tsconfig.json" }] } diff --git a/target/idl/token_bridge_relayer.json b/target/idl/token_bridge_relayer.json index 05c9bfaa..ee344daa 100644 --- a/target/idl/token_bridge_relayer.json +++ b/target/idl/token_bridge_relayer.json @@ -1,5 +1,5 @@ { - "address": "7TLiBkpDGshV4o3jmacTCx93CLkmo3VjZ111AsijN9f8", + "address": "46kv4wCpfEtLsHPDh4zm7jJb2pVdvke8Pj2ABYYJotFD", "metadata": { "name": "token_bridge_relayer", "version": "3.0.0", @@ -395,11 +395,11 @@ }, { "name": "wormhole_program", - "address": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + "address": "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5" }, { "name": "token_bridge_program", - "address": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb" + "address": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe" }, { "name": "rent", @@ -583,38 +583,38 @@ { "kind": "const", "value": [ - 95, - 229, - 130, - 69, 46, - 141, - 178, - 231, - 56, - 213, + 12, + 158, + 160, + 36, + 68, 199, - 161, - 79, - 236, - 191, - 130, - 165, - 181, - 246, - 134, - 44, - 135, - 169, - 19, - 212, - 103, - 182, - 152, - 69, - 169, - 9, - 75 + 53, + 193, + 188, + 121, + 0, + 45, + 72, + 226, + 163, + 188, + 92, + 29, + 151, + 151, + 123, + 73, + 1, + 120, + 85, + 125, + 88, + 159, + 229, + 38, + 196 ] } ], @@ -1294,11 +1294,11 @@ }, { "name": "token_bridge_program", - "address": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb" + "address": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe" }, { "name": "wormhole_program", - "address": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + "address": "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5" }, { "name": "clock", @@ -1631,16 +1631,16 @@ ] }, { - "name": "EvmPricesAccount", + "name": "EvmPricesState", "discriminator": [ - 222, - 30, - 172, - 90, - 189, - 184, - 118, - 31 + 96, + 16, + 101, + 97, + 209, + 101, + 197, + 178 ] }, { @@ -1657,16 +1657,16 @@ ] }, { - "name": "PriceOracleConfigAccount", + "name": "PriceOracleConfigState", "discriminator": [ - 192, - 215, - 139, - 0, - 191, - 210, - 185, - 218 + 86, + 37, + 173, + 69, + 170, + 230, + 127, + 150 ] }, { @@ -1842,13 +1842,20 @@ } }, { - "name": "EvmPricesAccount", + "name": "EvmPricesState", "docs": [ "EVM chains prices." ], "type": { "kind": "struct", "fields": [ + { + "name": "chain_id", + "docs": [ + "The chain that will be read or updated is identified by this field." + ], + "type": "u16" + }, { "name": "gas_price", "docs": [ @@ -1898,7 +1905,7 @@ } }, { - "name": "PriceOracleConfigAccount", + "name": "PriceOracleConfigState", "docs": [ "The program's main account." ], @@ -1912,20 +1919,6 @@ ], "type": "pubkey" }, - { - "name": "admin", - "docs": [ - "Program's admin. Can be used to update the prices or appoint a new assistant." - ], - "type": "pubkey" - }, - { - "name": "assistant", - "docs": [ - "Program's assistant. Can be used to update the prices." - ], - "type": "pubkey" - }, { "name": "pending_owner", "docs": [ diff --git a/target/types/token_bridge_relayer.ts b/target/types/token_bridge_relayer.ts index 86c5e708..dbbf9a40 100644 --- a/target/types/token_bridge_relayer.ts +++ b/target/types/token_bridge_relayer.ts @@ -5,7 +5,7 @@ * IDL can be found at `target/idl/token_bridge_relayer.json`. */ export type TokenBridgeRelayer = { - "address": "7TLiBkpDGshV4o3jmacTCx93CLkmo3VjZ111AsijN9f8", + "address": "46kv4wCpfEtLsHPDh4zm7jJb2pVdvke8Pj2ABYYJotFD", "metadata": { "name": "tokenBridgeRelayer", "version": "3.0.0", @@ -401,11 +401,11 @@ export type TokenBridgeRelayer = { }, { "name": "wormholeProgram", - "address": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + "address": "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5" }, { "name": "tokenBridgeProgram", - "address": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb" + "address": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe" }, { "name": "rent", @@ -589,38 +589,38 @@ export type TokenBridgeRelayer = { { "kind": "const", "value": [ - 95, - 229, - 130, - 69, 46, - 141, - 178, - 231, - 56, - 213, + 12, + 158, + 160, + 36, + 68, 199, - 161, - 79, - 236, - 191, - 130, - 165, - 181, - 246, - 134, - 44, - 135, - 169, - 19, - 212, - 103, - 182, - 152, - 69, - 169, - 9, - 75 + 53, + 193, + 188, + 121, + 0, + 45, + 72, + 226, + 163, + 188, + 92, + 29, + 151, + 151, + 123, + 73, + 1, + 120, + 85, + 125, + 88, + 159, + 229, + 38, + 196 ] } ], @@ -1300,11 +1300,11 @@ export type TokenBridgeRelayer = { }, { "name": "tokenBridgeProgram", - "address": "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb" + "address": "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe" }, { "name": "wormholeProgram", - "address": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + "address": "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5" }, { "name": "clock", @@ -1637,16 +1637,16 @@ export type TokenBridgeRelayer = { ] }, { - "name": "evmPricesAccount", + "name": "evmPricesState", "discriminator": [ - 222, - 30, - 172, - 90, - 189, - 184, - 118, - 31 + 96, + 16, + 101, + 97, + 209, + 101, + 197, + 178 ] }, { @@ -1663,16 +1663,16 @@ export type TokenBridgeRelayer = { ] }, { - "name": "priceOracleConfigAccount", + "name": "priceOracleConfigState", "discriminator": [ - 192, - 215, - 139, - 0, - 191, - 210, - 185, - 218 + 86, + 37, + 173, + 69, + 170, + 230, + 127, + 150 ] }, { @@ -1848,13 +1848,20 @@ export type TokenBridgeRelayer = { } }, { - "name": "evmPricesAccount", + "name": "evmPricesState", "docs": [ "EVM chains prices." ], "type": { "kind": "struct", "fields": [ + { + "name": "chainId", + "docs": [ + "The chain that will be read or updated is identified by this field." + ], + "type": "u16" + }, { "name": "gasPrice", "docs": [ @@ -1904,7 +1911,7 @@ export type TokenBridgeRelayer = { } }, { - "name": "priceOracleConfigAccount", + "name": "priceOracleConfigState", "docs": [ "The program's main account." ], @@ -1918,20 +1925,6 @@ export type TokenBridgeRelayer = { ], "type": "pubkey" }, - { - "name": "admin", - "docs": [ - "Program's admin. Can be used to update the prices or appoint a new assistant." - ], - "type": "pubkey" - }, - { - "name": "assistant", - "docs": [ - "Program's assistant. Can be used to update the prices." - ], - "type": "pubkey" - }, { "name": "pendingOwner", "docs": [ diff --git a/yarn.lock b/yarn.lock index 9af8d390..8c6a9c74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1604,12 +1604,12 @@ __metadata: languageName: node linkType: hard -"@wormhole-foundation/sdk-base@npm:^0.10.0": - version: 0.10.5 - resolution: "@wormhole-foundation/sdk-base@npm:0.10.5" +"@wormhole-foundation/sdk-base@npm:0.11.0, @wormhole-foundation/sdk-base@npm:^0.11": + version: 0.11.0 + resolution: "@wormhole-foundation/sdk-base@npm:0.11.0" dependencies: "@scure/base": "npm:^1.1.3" - checksum: 10c0/621cd97edc858ee9131aae4c11f10864ded4f31ffa48d8cb2ec9fefeffdc637055eb0a2cfe6a57e9b09a27c8c8f0bf3f18f4fc4bb9f729431759a1c5269869f4 + checksum: 10c0/5ff3faf68dcaef76df14cd413bed746f8849ad06ff96cb60f924c2cccee6df6b4a678f7ef3706ec4679d4b693e3da72ff9932b66e042adaac419e126fb44c0e4 languageName: node linkType: hard @@ -1624,6 +1624,17 @@ __metadata: languageName: node linkType: hard +"@wormhole-foundation/sdk-connect@npm:0.11.0": + version: 0.11.0 + resolution: "@wormhole-foundation/sdk-connect@npm:0.11.0" + dependencies: + "@wormhole-foundation/sdk-base": "npm:0.11.0" + "@wormhole-foundation/sdk-definitions": "npm:0.11.0" + axios: "npm:^1.4.0" + checksum: 10c0/475bcc4f326c96e81f4e17761f6dc794756268c442bb4028e68a4a720ccd4df9c13a7cae8d7fc6d742e11d09e9563f6c50ffdcd98c53cec537e66f9d93a5a380 + languageName: node + linkType: hard + "@wormhole-foundation/sdk-definitions@npm:0.10.9, @wormhole-foundation/sdk-definitions@npm:^0.10.9": version: 0.10.9 resolution: "@wormhole-foundation/sdk-definitions@npm:0.10.9" @@ -1635,6 +1646,17 @@ __metadata: languageName: node linkType: hard +"@wormhole-foundation/sdk-definitions@npm:0.11.0, @wormhole-foundation/sdk-definitions@npm:^0.11": + version: 0.11.0 + resolution: "@wormhole-foundation/sdk-definitions@npm:0.11.0" + dependencies: + "@noble/curves": "npm:^1.4.0" + "@noble/hashes": "npm:^1.3.1" + "@wormhole-foundation/sdk-base": "npm:0.11.0" + checksum: 10c0/f6f4c84d48da2d6da30a1f94ab7e2ca182b193cd02da4de15cb2375ca18f8dcd9f180ef68b954859d3c7dcc5f37c1e091c81e80dcf136409085fedf480cf6590 + languageName: node + linkType: hard + "@wormhole-foundation/sdk-evm@npm:0.10.9, @wormhole-foundation/sdk-evm@npm:^0.10.9": version: 0.10.9 resolution: "@wormhole-foundation/sdk-evm@npm:0.10.9" @@ -1645,34 +1667,48 @@ __metadata: languageName: node linkType: hard -"@wormhole-foundation/sdk-solana-core@npm:0.10.9, @wormhole-foundation/sdk-solana-core@npm:^0.10.9": - version: 0.10.9 - resolution: "@wormhole-foundation/sdk-solana-core@npm:0.10.9" +"@wormhole-foundation/sdk-solana-core@npm:0.11.0, @wormhole-foundation/sdk-solana-core@npm:^0.11": + version: 0.11.0 + resolution: "@wormhole-foundation/sdk-solana-core@npm:0.11.0" dependencies: "@coral-xyz/anchor": "npm:0.29.0" "@coral-xyz/borsh": "npm:0.29.0" "@solana/web3.js": "npm:^1.95.2" - "@wormhole-foundation/sdk-connect": "npm:0.10.9" - "@wormhole-foundation/sdk-solana": "npm:0.10.9" - checksum: 10c0/96153591733bd0c88eb4f1384e475d8fc93d4d0c38f5883eed1f0903fa9ec3f69f1597d9e479f6f941f1ce0e6d605477c96ba7f9900adbd4ab63ef1154421504 + "@wormhole-foundation/sdk-connect": "npm:0.11.0" + "@wormhole-foundation/sdk-solana": "npm:0.11.0" + checksum: 10c0/8174385288e9de376f7635dc10c1f1fc55e42a7b1dfe49f8660524db0134141573a544c83745f5d27a4c848ee42f51c61db24902179b52649a4c3498639a178c languageName: node linkType: hard -"@wormhole-foundation/sdk-solana-tokenbridge@npm:^0.10.9": - version: 0.10.9 - resolution: "@wormhole-foundation/sdk-solana-tokenbridge@npm:0.10.9" +"@wormhole-foundation/sdk-solana-tokenbridge@npm:^0.11": + version: 0.11.0 + resolution: "@wormhole-foundation/sdk-solana-tokenbridge@npm:0.11.0" dependencies: "@coral-xyz/anchor": "npm:0.29.0" "@solana/spl-token": "npm:0.3.9" "@solana/web3.js": "npm:^1.95.2" - "@wormhole-foundation/sdk-connect": "npm:0.10.9" - "@wormhole-foundation/sdk-solana": "npm:0.10.9" - "@wormhole-foundation/sdk-solana-core": "npm:0.10.9" - checksum: 10c0/4c722bfc0782a9bed00c2d58d938d2e2ab5731273811caef00e6ec83677aa04c7fa378874e1b58ed89cd1876b4c1df219615811e746976f97f04cbf898792d95 + "@wormhole-foundation/sdk-connect": "npm:0.11.0" + "@wormhole-foundation/sdk-solana": "npm:0.11.0" + "@wormhole-foundation/sdk-solana-core": "npm:0.11.0" + checksum: 10c0/bcc313d424ebf743ea51f8f24c9da29be1bbe08cae1184d22129991602fedcc7af44a96cccbebf9434b56575979eb846bcdf6368c63bd8985a1f4b1345a7fad0 languageName: node linkType: hard -"@wormhole-foundation/sdk-solana@npm:0.10.9, @wormhole-foundation/sdk-solana@npm:^0.10.9": +"@wormhole-foundation/sdk-solana@npm:0.11.0, @wormhole-foundation/sdk-solana@npm:^0.11": + version: 0.11.0 + resolution: "@wormhole-foundation/sdk-solana@npm:0.11.0" + dependencies: + "@coral-xyz/anchor": "npm:0.29.0" + "@coral-xyz/borsh": "npm:0.29.0" + "@solana/spl-token": "npm:0.3.9" + "@solana/web3.js": "npm:^1.95.2" + "@wormhole-foundation/sdk-connect": "npm:0.11.0" + rpc-websockets: "npm:^7.10.0" + checksum: 10c0/2134057b9e1d760b69105a9de3bcec16a87181fad1ae1e23d690301eef5f7f0be11564e7aab18d892e044e10b786708c419619df8faacde871a4503e948ea625 + languageName: node + linkType: hard + +"@wormhole-foundation/sdk-solana@npm:^0.10.9": version: 0.10.9 resolution: "@wormhole-foundation/sdk-solana@npm:0.10.9" dependencies: @@ -1747,11 +1783,11 @@ __metadata: "@coral-xyz/anchor": "npm:^0.30.1" "@solana/web3.js": "npm:^1.95.3" "@types/node": "npm:20.16.10" - "@wormhole-foundation/sdk-base": "npm:^0.10.9" - "@wormhole-foundation/sdk-definitions": "npm:^0.10.9" - "@wormhole-foundation/sdk-solana": "npm:^0.10.9" - "@wormhole-foundation/sdk-solana-tokenbridge": "npm:^0.10.9" - "@xlabs/solana-price-oracle-sdk": "npm:^0.0.7" + "@wormhole-foundation/sdk-base": "npm:^0.11" + "@wormhole-foundation/sdk-definitions": "npm:^0.11" + "@wormhole-foundation/sdk-solana": "npm:^0.11" + "@wormhole-foundation/sdk-solana-tokenbridge": "npm:^0.11" + "@xlabs/solana-price-oracle-sdk": "link:./lib/../../relayer-infra-contracts/src/solana/" borsh: "npm:^2.0.0" tsup: "npm:^8.3.0" tsx: "npm:4.19.1" @@ -1759,16 +1795,11 @@ __metadata: languageName: unknown linkType: soft -"@xlabs/solana-price-oracle-sdk@npm:^0.0.7": - version: 0.0.7 - resolution: "@xlabs/solana-price-oracle-sdk@npm:0.0.7::__archiveUrl=https%3A%2F%2Fnpm.pkg.github.com%2Fdownload%2F%40xlabs%2Fsolana-price-oracle-sdk%2F0.0.7%2F50706fa313c5a6f20564c024a5d7aef22ce95fc3" - dependencies: - "@coral-xyz/anchor": "npm:^0.30.1" - "@solana/web3.js": "npm:^1.95.2" - "@wormhole-foundation/sdk-base": "npm:^0.10.0" - checksum: 10c0/087932c718a17800482018fc1fb3415dbe7a737d10f6a53d721b64d5e3d6204c76d9d9bc6e7cbb5b0c21be6a44c4f948d2d22779d7ed8f7f00b269806a2925a3 +"@xlabs/solana-price-oracle-sdk@link:./lib/../../relayer-infra-contracts/src/solana/::locator=%40xlabs-xyz%2Fsolana-arbitrary-token-transfers%40workspace%3Asdk%2Fsolana": + version: 0.0.0-use.local + resolution: "@xlabs/solana-price-oracle-sdk@link:./lib/../../relayer-infra-contracts/src/solana/::locator=%40xlabs-xyz%2Fsolana-arbitrary-token-transfers%40workspace%3Asdk%2Fsolana" languageName: node - linkType: hard + linkType: soft "@yarnpkg/types@npm:^4.0.0": version: 4.0.0 @@ -4933,10 +4964,10 @@ __metadata: "@solana/web3.js": "npm:^1.95.3" "@types/chai": "npm:^4.3.19" "@types/mocha": "npm:8.*" - "@wormhole-foundation/sdk-base": "npm:^0.10.9" - "@wormhole-foundation/sdk-definitions": "npm:^0.10.9" - "@wormhole-foundation/sdk-solana-core": "npm:^0.10.9" - "@wormhole-foundation/sdk-solana-tokenbridge": "npm:^0.10.9" + "@wormhole-foundation/sdk-base": "npm:^0.11" + "@wormhole-foundation/sdk-definitions": "npm:^0.11" + "@wormhole-foundation/sdk-solana-core": "npm:^0.11" + "@wormhole-foundation/sdk-solana-tokenbridge": "npm:^0.11" "@xlabs-xyz/solana-arbitrary-token-transfers": "workspace:^" chai: "npm:^5.1.1" mocha: "npm:8.*"