@@ -2,154 +2,173 @@ import * as anchor from "@coral-xyz/anchor";
2
2
import * as spl from "@solana/spl-token" ;
3
3
import type { AccountInfo , AccountMeta } from "@solana/web3.js" ;
4
4
import {
5
- AddressLookupTableProgram ,
6
- Connection ,
7
- Keypair ,
8
- MessageV0 ,
9
- PublicKey ,
10
- sendAndConfirmTransaction ,
11
- SystemProgram ,
12
- Transaction ,
13
- TransactionInstruction ,
14
- TransactionMessage ,
15
- VersionedTransaction ,
5
+ AddressLookupTableProgram ,
6
+ Connection ,
7
+ Keypair ,
8
+ MessageV0 ,
9
+ PublicKey ,
10
+ sendAndConfirmTransaction ,
11
+ SystemProgram ,
12
+ Transaction ,
13
+ TransactionInstruction ,
14
+ TransactionMessage ,
15
+ VersionedTransaction ,
16
+ AddressLookupTableAccount ,
16
17
} from "@solana/web3.js" ;
18
+ var resolve = require ( "resolve-dir" ) ;
17
19
import { Big , BigUtils , bs58 } from "@switchboard-xyz/common" ;
18
20
import { OracleJob } from "@switchboard-xyz/common" ;
19
- import * as sb from "@switchboard-xyz/solana.js " ;
21
+ import * as sb from "@switchboard-xyz/on-demand " ;
20
22
import { toBufferLE } from "bigint-buffer" ;
21
23
import * as crypto from "crypto" ;
22
24
import * as fs from "fs" ;
23
25
const assert = require ( "assert" ) ;
24
-
25
- const walletFile = "/home/scottk/workspace/creds/devnet-wallet" ;
26
- // example "/Users/mgild/switchboard_environments_v2/devnet/upgrade_authority/test.json"
27
- const payerFile = "/home/scottk/workspace/creds/devnet-wallet"
28
- let PID = new PublicKey ( "sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx" ) ;
29
- // PID = new PublicKey("CR1hCrkKveeWrYYs5kk7rasRM2AH1vZy8s8fn42NBwkq");
30
- const RPC_URL = "https://api.devnet.solana.com" ;
31
-
32
-
33
-
34
- async function fetchLatestSlotHash (
35
- connection : Connection
36
- ) : Promise < [ bigint , string ] > {
37
- const slotHashesSysvarKey = new PublicKey (
38
- "SysvarS1otHashes111111111111111111111111111"
39
- ) ;
40
- const accountInfo = await connection . getAccountInfo ( slotHashesSysvarKey , {
41
- commitment : "confirmed" ,
42
- dataSlice : { length : 40 , offset : 8 } ,
43
- } ) ;
44
- let buffer = accountInfo ! . data ;
45
- const slotNumber = buffer . readBigUInt64LE ( ) ;
46
- buffer = buffer . slice ( 8 ) ;
47
- return [ slotNumber , bs58 . encode ( buffer ) ] ;
48
- }
49
-
50
- async function initWalletFromFile ( filePath : string ) : Promise < anchor . Wallet > {
51
- // Read the file
52
- const secretKeyString : string = fs . readFileSync ( filePath , {
53
- encoding : "utf8" ,
54
- } ) ;
55
- const secretKey : Uint8Array = Uint8Array . from ( JSON . parse ( secretKeyString ) ) ;
56
-
57
- // Create a keypair from the secret key
58
- const keypair : Keypair = Keypair . fromSecretKey ( secretKey ) ;
59
-
60
- // Create a wallet
61
- const wallet : anchor . Wallet = new anchor . Wallet ( keypair ) ;
62
-
63
- return wallet ;
64
- }
65
-
66
- async function initKeypairFromFile ( filePath : string ) : Promise < Keypair > {
67
- // Read the file
68
- const secretKeyString : string = fs . readFileSync ( filePath , {
69
- encoding : "utf8" ,
70
- } ) ;
71
- const secretKey : Uint8Array = Uint8Array . from ( JSON . parse ( secretKeyString ) ) ;
72
-
73
- // Create a keypair from the secret key
74
- const keypair : Keypair = Keypair . fromSecretKey ( secretKey ) ;
75
-
76
- return keypair ;
26
+ const yargs = require ( "yargs/yargs" ) ;
27
+ import {
28
+ InstructionUtils ,
29
+ PullFeed ,
30
+ Queue ,
31
+ RecentSlotHashes ,
32
+ } from "@switchboard-xyz/on-demand" ;
33
+
34
+ // ts-node bootstrap.ts --queueKey=7n7CSKBhqxM9m9YyLPn7cF6vXvxtZAWMBW42ior8qode --guardianQueue=F4pXZNjaaNmGwXzBhoxs5yaH6f6RKKkj5qgCZKPF9rjg --payerPath=/home/scottk/workspace/creds/devops-keypair.json
35
+
36
+ let argv = yargs ( process . argv ) . options ( {
37
+ queueKey : {
38
+ type : "string" ,
39
+ describe : "Queue to put pull oracle on" ,
40
+ demand : false ,
41
+ default : "" ,
42
+ } ,
43
+ guardianQueue : {
44
+ type : "string" ,
45
+ describe : "Queue to put guardian oracle on" ,
46
+ demand : false ,
47
+ default : "" ,
48
+ } ,
49
+ initQueues : {
50
+ type : "boolean" ,
51
+ describe : "Initialize new queues" ,
52
+ demand : false ,
53
+ default : false ,
54
+ } ,
55
+ payerPath : {
56
+ type : "string" ,
57
+ describe : "Path to payer keypair" ,
58
+ demand : true ,
59
+ } ,
60
+ } ) . argv ;
61
+
62
+ async function sendIx (
63
+ program : anchor . Program ,
64
+ ix : TransactionInstruction ,
65
+ signers : Array < Keypair >
66
+ ) {
67
+ const tx = await InstructionUtils . asV0Tx ( program , [ ix ] , [ ] ) ;
68
+ for ( const signer of signers ) {
69
+ tx . sign ( [ signer ] ) ;
70
+ }
71
+ const sig = await program . provider . connection . sendTransaction ( tx ) ;
72
+ console . log ( `signature: ${ sig } ` ) ;
77
73
}
78
74
79
- async function keypairFromJson ( secretKeyString : string ) : Promise < Keypair > {
80
- const secretKey : Uint8Array = Uint8Array . from ( JSON . parse ( secretKeyString ) ) ;
81
-
82
- // Create a keypair from the secret key
83
- return Keypair . fromSecretKey ( secretKey ) ;
75
+ function keypairFromJson ( secretKeyString : string ) : Keypair {
76
+ const secretKey : Uint8Array = Uint8Array . from ( JSON . parse ( secretKeyString ) ) ;
77
+ return Keypair . fromSecretKey ( secretKey ) ;
84
78
}
85
79
86
- export function logEnvVariables (
87
- env : Array < [ string , string | anchor . web3 . PublicKey ] > ,
88
- pre = "Make sure to add the following to your .env file:"
89
- ) {
90
- console . log (
91
- `\n${ pre } \n\t${ env
92
- . map ( ( [ key , value ] ) => `${ key . toUpperCase ( ) } =${ value } ` )
93
- . join ( "\n\t" ) } \n`
94
- ) ;
80
+ function initKeypairFromFile ( filePath : string ) : Keypair {
81
+ const secretKeyString = fs . readFileSync ( filePath , { encoding : "utf8" } ) ;
82
+ return keypairFromJson ( secretKeyString ) ;
95
83
}
96
84
97
85
( async ( ) => {
98
- const ORACLE_IP = "127.0.0.1" ;
99
-
100
- let PID = new PublicKey ( "sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx" ) ;
101
- PID = sb . SB_ON_DEMAND_PID ;
102
- const connection = new Connection (
103
- RPC_URL ,
104
- "confirmed"
105
- ) ;
106
-
107
- const wallet = await initWalletFromFile (
108
- walletFile
109
- ) ;
110
- const devnetPayer = await initKeypairFromFile (
111
- payerFile
86
+ let PID ;
87
+ PID = sb . SB_ON_DEMAND_PID ;
88
+ const connection = new Connection (
89
+ "https://api.devnet.solana.com" ,
90
+ "confirmed"
91
+ ) ;
92
+ const devnetPayer = initKeypairFromFile (
93
+ resolve ( argv . payerPath || "./payer.json" )
94
+ ) ;
95
+ const wallet = new anchor . Wallet ( devnetPayer ) ;
96
+ const provider = new anchor . AnchorProvider ( connection , wallet , { } ) ;
97
+ const idl = await anchor . Program . fetchIdl ( PID , provider ) ;
98
+ const program = new anchor . Program ( idl ! , PID , provider ) ;
99
+ let queueKey = argv . queueKey ;
100
+ let guardianQueueKey = argv . guardianQueue ;
101
+ console . log ( `Queue: ${ queueKey } ` ) ;
102
+ console . log ( `GuardianQueue: ${ guardianQueueKey } ` ) ;
103
+ if ( argv . initQueues ) {
104
+ try {
105
+ const [ state , stateInitSig ] = await sb . State . create ( program ) ;
106
+ console . log ( `State: ${ state . pubkey . toBase58 ( ) } Sig: ${ stateInitSig } ` ) ;
107
+ } catch ( e ) { }
108
+ const state = new sb . State ( program ) ;
109
+ const [ queue , queueCreateSig ] = await sb . Queue . create ( program , { } ) ;
110
+ console . log ( `Queue: ${ queue . pubkey . toBase58 ( ) } Sig: ${ queueCreateSig } ` ) ;
111
+ queueKey = queue . pubkey . toBase58 ( ) ;
112
+ const [ guardianQueue , guardianQueueCreateSig ] = await sb . Queue . create (
113
+ program ,
114
+ { }
112
115
) ;
113
- const provider = new anchor . AnchorProvider ( connection , wallet , { } ) ;
114
- const idl = await anchor . Program . fetchIdl ( PID , provider ) ;
115
- const program = new anchor . Program ( idl ! , PID , provider ) ;
116
- const switchboardProgram = sb . SwitchboardProgram . from (
117
- connection ,
118
- devnetPayer ,
119
- sb . SB_V2_PID ,
120
- PID
116
+ guardianQueueKey = guardianQueue . pubkey . toBase58 ( ) ;
117
+ console . log (
118
+ `GuardianQueue: ${ queue . pubkey . toBase58 ( ) } Sig: ${ guardianQueueCreateSig } `
121
119
) ;
122
-
123
- const [ slotNumber , slotHash ] = await fetchLatestSlotHash ( connection ) ;
124
- const bootstrappedQueue = ( await sb . AttestationQueueAccount . bootstrapNewQueue (
125
- switchboardProgram
126
- ) ) as any ;
127
- console . log ( bootstrappedQueue ) ;
128
-
129
- const attestationQueueAccount = bootstrappedQueue . attestationQueue . account ;
130
- const verifierOracleAccount = bootstrappedQueue . verifier . account ;
131
- const quoteKeypair2 = Keypair . generate ( ) ;
132
-
133
- const [ verifier2 , signature ] = await attestationQueueAccount . createVerifier ( {
134
- createPermissions : true ,
135
- keypair : quoteKeypair2 ,
120
+ const setConfigIx = await state . setConfigsIx ( {
121
+ queue : guardianQueue . pubkey ,
122
+ newAuthority : devnetPayer . publicKey ,
123
+ minQuoteVerifyVotes : new anchor . BN ( 1 ) ,
124
+ } ) ;
125
+ const setConfigTx = await InstructionUtils . asV0Tx ( program , [ setConfigIx ] ) ;
126
+ setConfigTx . sign ( [ devnetPayer ] ) ;
127
+ const setConfigSig = await connection . sendTransaction ( setConfigTx ) ;
128
+ console . log ( `Set Config Sig: ${ setConfigSig } ` ) ;
129
+ }
130
+ const queue = new sb . Queue ( program , new PublicKey ( queueKey ) ) ;
131
+ const guardianQueue = new sb . Queue ( program , new PublicKey ( guardianQueueKey ) ) ;
132
+ const stateAccount = new sb . State ( program ) ;
133
+ const state = new sb . State ( program ) ;
134
+ const [ oracle1 , oracleCreateSig1 ] = await sb . Oracle . create ( program , {
135
+ queue : queue . pubkey ,
136
+ } ) ;
137
+ const [ guardianOracle1 , goracleCreateSig1 ] = await sb . Oracle . create ( program , {
138
+ queue : guardianQueue . pubkey ,
139
+ } ) ;
140
+ if ( argv . initQueues ) {
141
+ await sendIx (
142
+ program ,
143
+ await sb . Permission . setIx ( program , {
144
+ authority : devnetPayer . publicKey ,
145
+ grantee : oracle1 . pubkey ,
146
+ granter : queue . pubkey ,
136
147
enable : true ,
137
- queueAuthorityPubkey : devnetPayer . publicKey ,
148
+ permission : sb . SwitchboardPermission . PermitOracleHeartbeat ,
149
+ } ) ,
150
+ [ devnetPayer ]
151
+ ) ;
152
+ await sendIx (
153
+ program ,
154
+ await sb . Permission . setIx ( program , {
138
155
authority : devnetPayer . publicKey ,
139
- queueAccount : attestationQueueAccount . publicKey ,
140
- registryKey : new Uint8Array ( 64 ) . fill ( 0 ) ,
141
- } ) ;
142
- console . log ( verifier2 . publicKey ) ;
143
-
144
- logEnvVariables ( [
145
- [ "SWITCHBOARD_ATTESTATION_QUEUE_KEY" , attestationQueueAccount . publicKey ] ,
146
- [ "SWITCHBOARD_VERIFIER_ORACLE_KEY" , verifierOracleAccount . publicKey ] ,
147
- [ "SWITCHBOARD_VERIFIER_ORACLE_KEY2" , verifier2 . publicKey . toString ( ) ] ,
148
- ] ) ;
149
-
150
- const y = bootstrappedQueue . signatures . map ( ( s : any , i : any ) : any => {
151
- return { name : `bootstrap_queue #${ i + 1 } ` , tx : s } ;
152
- } ) ;
153
- console . log ( y ) ;
154
- return ;
156
+ granter : guardianQueue . pubkey ,
157
+ grantee : guardianOracle1 . pubkey ,
158
+ enable : true ,
159
+ permission : sb . SwitchboardPermission . PermitOracleHeartbeat ,
160
+ } ) ,
161
+ [ devnetPayer ]
162
+ ) ;
163
+ }
164
+
165
+ console . log ( `
166
+ export QUEUE=${ queue . pubkey . toBase58 ( ) }
167
+ export GUARDIAN_QUEUE=${ guardianQueue . pubkey . toBase58 ( ) }
168
+ export STATE=${ state . pubkey . toBase58 ( ) }
169
+ export PID=${ PID . toBase58 ( ) }
170
+ export ORACLE1=${ oracle1 . pubkey . toBase58 ( ) }
171
+ export GUARDIAN_ORACLE1=${ guardianOracle1 . pubkey . toBase58 ( ) }
172
+ ` ) ;
173
+ return ;
155
174
} ) ( ) ;
0 commit comments