diff --git a/express_relay/sdk/js/README.md b/express_relay/sdk/js/README.md index e9ad21a09c..b535b88e2e 100644 --- a/express_relay/sdk/js/README.md +++ b/express_relay/sdk/js/README.md @@ -24,7 +24,7 @@ To generate the latest type declarations from the server openapi schema, run: npm run generate-api-types ``` -You can generate the Solana Typescript declaration files from the IDLs via: +You can generate the SVM Typescript declaration files from the IDLs via: ```bash npm run generate-anchor-types diff --git a/express_relay/sdk/js/package.json b/express_relay/sdk/js/package.json index 790ef79453..940489314a 100644 --- a/express_relay/sdk/js/package.json +++ b/express_relay/sdk/js/package.json @@ -1,6 +1,6 @@ { "name": "@pythnetwork/express-relay-js", - "version": "0.9.0", + "version": "0.9.1", "description": "Utilities for interacting with the express relay protocol", "homepage": "https://github.com/pyth-network/pyth-crosschain/tree/main/express_relay/sdk/js", "author": "Douro Labs", diff --git a/express_relay/sdk/js/src/const.ts b/express_relay/sdk/js/src/const.ts index d869431c93..557530f898 100644 --- a/express_relay/sdk/js/src/const.ts +++ b/express_relay/sdk/js/src/const.ts @@ -24,7 +24,7 @@ export const OPPORTUNITY_ADAPTER_CONFIGS: Record< }; export const SVM_CONSTANTS: Record = { - solana: { + "development-solana": { relayerSigner: new PublicKey( "3pR5W8qPTHKEdoD7mNMx1SwkaPE18aQZwoAKWYpnHozY" ), diff --git a/express_relay/sdk/js/src/examples/dummyTypes.d.ts b/express_relay/sdk/js/src/examples/dummyTypes.d.ts index 49003e21e1..7e16b2a59a 100644 --- a/express_relay/sdk/js/src/examples/dummyTypes.d.ts +++ b/express_relay/sdk/js/src/examples/dummyTypes.d.ts @@ -8,7 +8,7 @@ export type Dummy = { address: "HYCgALnu6CM2gkQVopa1HGaNf8Vzbs9bomWRiKP267P3"; metadata: { name: "dummy"; - version: "0.1.0"; + version: "0.2.0"; spec: "0.1.0"; description: "Created with Anchor"; }; @@ -26,6 +26,21 @@ export type Dummy = { name: "expressRelay"; address: "GwEtasTAxdS9neVE4GPUpcwR7DB7AizntQSPcG36ubZM"; }, + { + name: "expressRelayMetadata"; + pda: { + seeds: [ + { + kind: "const"; + value: [109, 101, 116, 97, 100, 97, 116, 97]; + } + ]; + program: { + kind: "account"; + path: "expressRelay"; + }; + }; + }, { name: "sysvarInstructions"; address: "Sysvar1nstructions1111111111111111111111111"; @@ -35,9 +50,110 @@ export type Dummy = { }, { name: "router"; + }, + { + name: "configRouter"; + pda: { + seeds: [ + { + kind: "const"; + value: [ + 99, + 111, + 110, + 102, + 105, + 103, + 95, + 114, + 111, + 117, + 116, + 101, + 114 + ]; + }, + { + kind: "account"; + path: "router"; + } + ]; + program: { + kind: "account"; + path: "expressRelay"; + }; + }; + }, + { + name: "accounting"; + writable: true; + pda: { + seeds: [ + { + kind: "const"; + value: [97, 99, 99, 111, 117, 110, 116, 105, 110, 103]; + } + ]; + }; + }, + { + name: "systemProgram"; + address: "11111111111111111111111111111111"; } ]; args: []; } ]; + accounts: [ + { + name: "accounting"; + discriminator: [1, 249, 15, 214, 81, 88, 40, 108]; + }, + { + name: "expressRelayMetadata"; + discriminator: [204, 75, 133, 7, 175, 241, 130, 11]; + } + ]; + types: [ + { + name: "accounting"; + type: { + kind: "struct"; + fields: [ + { + name: "totalFees"; + type: "u64"; + } + ]; + }; + }, + { + name: "expressRelayMetadata"; + type: { + kind: "struct"; + fields: [ + { + name: "admin"; + type: "pubkey"; + }, + { + name: "relayerSigner"; + type: "pubkey"; + }, + { + name: "feeReceiverRelayer"; + type: "pubkey"; + }, + { + name: "splitRouterDefault"; + type: "u64"; + }, + { + name: "splitRelayer"; + type: "u64"; + } + ]; + }; + } + ]; }; diff --git a/express_relay/sdk/js/src/examples/idl/idlDummy.json b/express_relay/sdk/js/src/examples/idl/idlDummy.json index b1917f29d0..6199c59463 100644 --- a/express_relay/sdk/js/src/examples/idl/idlDummy.json +++ b/express_relay/sdk/js/src/examples/idl/idlDummy.json @@ -2,7 +2,7 @@ "address": "HYCgALnu6CM2gkQVopa1HGaNf8Vzbs9bomWRiKP267P3", "metadata": { "name": "dummy", - "version": "0.1.0", + "version": "0.2.0", "spec": "0.1.0", "description": "Created with Anchor" }, @@ -20,6 +20,21 @@ "name": "express_relay", "address": "GwEtasTAxdS9neVE4GPUpcwR7DB7AizntQSPcG36ubZM" }, + { + "name": "express_relay_metadata", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [109, 101, 116, 97, 100, 97, 116, 97] + } + ], + "program": { + "kind": "account", + "path": "express_relay" + } + } + }, { "name": "sysvar_instructions", "address": "Sysvar1nstructions1111111111111111111111111" @@ -29,9 +44,98 @@ }, { "name": "router" + }, + { + "name": "config_router", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 99, 111, 110, 102, 105, 103, 95, 114, 111, 117, 116, 101, 114 + ] + }, + { + "kind": "account", + "path": "router" + } + ], + "program": { + "kind": "account", + "path": "express_relay" + } + } + }, + { + "name": "accounting", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "const", + "value": [97, 99, 99, 111, 117, 110, 116, 105, 110, 103] + } + ] + } + }, + { + "name": "system_program", + "address": "11111111111111111111111111111111" } ], "args": [] } + ], + "accounts": [ + { + "name": "Accounting", + "discriminator": [1, 249, 15, 214, 81, 88, 40, 108] + }, + { + "name": "ExpressRelayMetadata", + "discriminator": [204, 75, 133, 7, 175, 241, 130, 11] + } + ], + "types": [ + { + "name": "Accounting", + "type": { + "kind": "struct", + "fields": [ + { + "name": "total_fees", + "type": "u64" + } + ] + } + }, + { + "name": "ExpressRelayMetadata", + "type": { + "kind": "struct", + "fields": [ + { + "name": "admin", + "type": "pubkey" + }, + { + "name": "relayer_signer", + "type": "pubkey" + }, + { + "name": "fee_receiver_relayer", + "type": "pubkey" + }, + { + "name": "split_router_default", + "type": "u64" + }, + { + "name": "split_relayer", + "type": "u64" + } + ] + } + } ] } diff --git a/express_relay/sdk/js/src/examples/simpleSearcherSvm.ts b/express_relay/sdk/js/src/examples/simpleSearcherSvm.ts index a7107a5fa2..bc815839bc 100644 --- a/express_relay/sdk/js/src/examples/simpleSearcherSvm.ts +++ b/express_relay/sdk/js/src/examples/simpleSearcherSvm.ts @@ -9,10 +9,13 @@ import { Program, AnchorProvider } from "@coral-xyz/anchor"; import { Keypair, PublicKey, Connection } from "@solana/web3.js"; import dummyIdl from "./idl/idlDummy.json"; import { Dummy } from "./dummyTypes"; +import { getConfigRouterPda, getExpressRelayMetadataPda } from "../svmPda"; const DAY_IN_SECONDS = 60 * 60 * 24; const DUMMY_PIDS: Record = { - solana: new PublicKey("HYCgALnu6CM2gkQVopa1HGaNf8Vzbs9bomWRiKP267P3"), + "development-solana": new PublicKey( + "HYCgALnu6CM2gkQVopa1HGaNf8Vzbs9bomWRiKP267P3" + ), }; class SimpleSearcherSvm { @@ -69,7 +72,6 @@ class SimpleSearcherSvm { const permission = PublicKey.default; const router = Keypair.generate().publicKey; - const bidAmount = new anchor.BN(argv.bid); const svmConstants = SVM_CONSTANTS[this.chainId]; if (!(this.chainId in DUMMY_PIDS)) { @@ -77,14 +79,27 @@ class SimpleSearcherSvm { } const dummyPid = DUMMY_PIDS[this.chainId]; + const configRouter = getConfigRouterPda(this.chainId, router); + const expressRelayMetadata = getExpressRelayMetadataPda(this.chainId); + const accounting = PublicKey.findProgramAddressSync( + [anchor.utils.bytes.utf8.encode("accounting")], + dummyPid + )[0]; + + const bidAmount = new anchor.BN(argv.bid); + const ixDummy = await dummy.methods .doNothing() .accountsStrict({ payer: searcher.publicKey, expressRelay: svmConstants.expressRelayProgram, + expressRelayMetadata, sysvarInstructions: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY, permission, router, + configRouter, + accounting, + systemProgram: anchor.web3.SystemProgram.programId, }) .instruction(); ixDummy.programId = dummyPid; diff --git a/express_relay/sdk/js/src/expressRelayTypes.d.ts b/express_relay/sdk/js/src/expressRelayTypes.d.ts index 7e20e1a21a..c85e495408 100644 --- a/express_relay/sdk/js/src/expressRelayTypes.d.ts +++ b/express_relay/sdk/js/src/expressRelayTypes.d.ts @@ -8,13 +8,19 @@ export type ExpressRelay = { address: "GwEtasTAxdS9neVE4GPUpcwR7DB7AizntQSPcG36ubZM"; metadata: { name: "expressRelay"; - version: "0.1.0"; + version: "0.2.0"; spec: "0.1.0"; - description: "Created with Anchor"; + description: "Pyth Express Relay program for handling permissioning and bid distribution"; + repository: "https://github.com/pyth-network/per"; }; instructions: [ { name: "checkPermission"; + docs: [ + "Checks if permissioning exists for a particular (permission, router) pair within the same transaction", + "Permissioning takes the form of a SubmitBid instruction with matching permission and router accounts", + "Returns the fees paid to the router in the matching instructions" + ]; discriminator: [154, 199, 232, 242, 96, 72, 197, 236]; accounts: [ { @@ -26,9 +32,50 @@ export type ExpressRelay = { }, { name: "router"; + }, + { + name: "configRouter"; + pda: { + seeds: [ + { + kind: "const"; + value: [ + 99, + 111, + 110, + 102, + 105, + 103, + 95, + 114, + 111, + 117, + 116, + 101, + 114 + ]; + }, + { + kind: "account"; + path: "router"; + } + ]; + }; + }, + { + name: "expressRelayMetadata"; + pda: { + seeds: [ + { + kind: "const"; + value: [109, 101, 116, 97, 100, 97, 116, 97]; + } + ]; + }; } ]; args: []; + returns: "u64"; }, { name: "initialize"; @@ -146,7 +193,7 @@ export type ExpressRelay = { relations: ["expressRelayMetadata"]; }, { - name: "routerConfig"; + name: "configRouter"; writable: true; pda: { seeds: [ @@ -241,6 +288,9 @@ export type ExpressRelay = { }, { name: "submitBid"; + docs: [ + "Submits a bid for a particular (permission, router) pair and distributes bids according to splits" + ]; discriminator: [19, 164, 237, 254, 64, 139, 237, 93]; accounts: [ { @@ -261,7 +311,7 @@ export type ExpressRelay = { writable: true; }, { - name: "routerConfig"; + name: "configRouter"; pda: { seeds: [ { @@ -289,11 +339,6 @@ export type ExpressRelay = { ]; }; }, - { - name: "feeReceiverRelayer"; - writable: true; - relations: ["expressRelayMetadata"]; - }, { name: "expressRelayMetadata"; writable: true; @@ -306,6 +351,11 @@ export type ExpressRelay = { ]; }; }, + { + name: "feeReceiverRelayer"; + writable: true; + relations: ["expressRelayMetadata"]; + }, { name: "systemProgram"; address: "11111111111111111111111111111111"; diff --git a/express_relay/sdk/js/src/idl/idlExpressRelay.json b/express_relay/sdk/js/src/idl/idlExpressRelay.json index 42a046f9a5..a185fdfcac 100644 --- a/express_relay/sdk/js/src/idl/idlExpressRelay.json +++ b/express_relay/sdk/js/src/idl/idlExpressRelay.json @@ -2,13 +2,19 @@ "address": "GwEtasTAxdS9neVE4GPUpcwR7DB7AizntQSPcG36ubZM", "metadata": { "name": "express_relay", - "version": "0.1.0", + "version": "0.2.0", "spec": "0.1.0", - "description": "Created with Anchor" + "description": "Pyth Express Relay program for handling permissioning and bid distribution", + "repository": "https://github.com/pyth-network/per" }, "instructions": [ { "name": "check_permission", + "docs": [ + "Checks if permissioning exists for a particular (permission, router) pair within the same transaction", + "Permissioning takes the form of a SubmitBid instruction with matching permission and router accounts", + "Returns the fees paid to the router in the matching instructions" + ], "discriminator": [154, 199, 232, 242, 96, 72, 197, 236], "accounts": [ { @@ -20,9 +26,38 @@ }, { "name": "router" + }, + { + "name": "config_router", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [ + 99, 111, 110, 102, 105, 103, 95, 114, 111, 117, 116, 101, 114 + ] + }, + { + "kind": "account", + "path": "router" + } + ] + } + }, + { + "name": "express_relay_metadata", + "pda": { + "seeds": [ + { + "kind": "const", + "value": [109, 101, 116, 97, 100, 97, 116, 97] + } + ] + } } ], - "args": [] + "args": [], + "returns": "u64" }, { "name": "initialize", @@ -140,7 +175,7 @@ "relations": ["express_relay_metadata"] }, { - "name": "router_config", + "name": "config_router", "writable": true, "pda": { "seeds": [ @@ -223,6 +258,9 @@ }, { "name": "submit_bid", + "docs": [ + "Submits a bid for a particular (permission, router) pair and distributes bids according to splits" + ], "discriminator": [19, 164, 237, 254, 64, 139, 237, 93], "accounts": [ { @@ -243,7 +281,7 @@ "writable": true }, { - "name": "router_config", + "name": "config_router", "pda": { "seeds": [ { @@ -259,11 +297,6 @@ ] } }, - { - "name": "fee_receiver_relayer", - "writable": true, - "relations": ["express_relay_metadata"] - }, { "name": "express_relay_metadata", "writable": true, @@ -276,6 +309,11 @@ ] } }, + { + "name": "fee_receiver_relayer", + "writable": true, + "relations": ["express_relay_metadata"] + }, { "name": "system_program", "address": "11111111111111111111111111111111" diff --git a/express_relay/sdk/js/src/index.ts b/express_relay/sdk/js/src/index.ts index 64310dbbe9..abcfce0c30 100644 --- a/express_relay/sdk/js/src/index.ts +++ b/express_relay/sdk/js/src/index.ts @@ -36,6 +36,7 @@ import * as anchor from "@coral-xyz/anchor"; import { AnchorProvider, Program } from "@coral-xyz/anchor"; import expressRelayIdl from "./idl/idlExpressRelay.json"; import { ExpressRelay } from "./expressRelayTypes"; +import { getConfigRouterPda, getExpressRelayMetadataPda } from "./svmPda"; export * from "./types"; @@ -638,18 +639,10 @@ export class Client { {} as AnchorProvider ); + const configRouter = getConfigRouterPda(chainId, router); + const expressRelayMetadata = getExpressRelayMetadataPda(chainId); const svmConstants = SVM_CONSTANTS[chainId]; - const routerConfig = PublicKey.findProgramAddressSync( - [anchor.utils.bytes.utf8.encode("config_router"), router.toBuffer()], - svmConstants.expressRelayProgram - )[0]; - - const expressRelayMetadata = PublicKey.findProgramAddressSync( - [anchor.utils.bytes.utf8.encode("metadata")], - svmConstants.expressRelayProgram - )[0]; - const ixSubmitBid = await expressRelay.methods .submitBid({ deadline, @@ -660,9 +653,9 @@ export class Client { relayerSigner: svmConstants.relayerSigner, permission: permissionKey, router, - routerConfig, - feeReceiverRelayer: svmConstants.feeReceiverRelayer, + configRouter, expressRelayMetadata, + feeReceiverRelayer: svmConstants.feeReceiverRelayer, systemProgram: anchor.web3.SystemProgram.programId, sysvarInstructions: anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY, }) diff --git a/express_relay/sdk/js/src/svmPda.ts b/express_relay/sdk/js/src/svmPda.ts new file mode 100644 index 0000000000..970c8c2802 --- /dev/null +++ b/express_relay/sdk/js/src/svmPda.ts @@ -0,0 +1,23 @@ +import { PublicKey } from "@solana/web3.js"; +import { SVM_CONSTANTS } from "./const"; + +export function getConfigRouterPda( + chain: string, + router: PublicKey +): PublicKey { + const expressRelayProgram = SVM_CONSTANTS[chain].expressRelayProgram; + + return PublicKey.findProgramAddressSync( + [Buffer.from("config_router"), router.toBuffer()], + expressRelayProgram + )[0]; +} + +export function getExpressRelayMetadataPda(chain: string): PublicKey { + const expressRelayProgram = SVM_CONSTANTS[chain].expressRelayProgram; + + return PublicKey.findProgramAddressSync( + [Buffer.from("metadata")], + expressRelayProgram + )[0]; +}