@@ -11,6 +11,7 @@ import { PublicKey } from '@solana/web3.js'
1111import { Idl , IdlField , IdlType , IdlAccountItem } from '@coral-xyz/anchor/dist/cjs/idl'
1212import { IdlCoder } from './idl'
1313import { InstructionCoder } from '@coral-xyz/anchor'
14+ import { Product } from '../..'
1415
1516export type PythIdlInstruction = {
1617 name : string
@@ -79,14 +80,32 @@ export class PythOracleInstructionCoder implements InstructionCoder {
7980 public encode ( ixName : string , ix : any ) : Buffer {
8081 const buffer = Buffer . alloc ( 1000 ) // TODO: use a tighter buffer.
8182 const methodName = camelCase ( ixName )
83+
8284 const layout = this . ixLayout . get ( methodName )
8385 const discriminator = this . ixDiscriminator . get ( methodName )
8486 if ( ! layout || ! discriminator ) {
8587 throw new Error ( `Unknown method: ${ methodName } ` )
8688 }
87- const len = layout . encode ( ix , buffer )
88- const data = buffer . subarray ( 0 , len )
89- return Buffer . concat ( [ discriminator , data ] )
89+
90+ /// updProduct has its own format
91+ if ( methodName === 'updProduct' ) {
92+ let offset = 0
93+ for ( const key of Object . keys ( ix . productMetadata ) ) {
94+ offset += buffer . subarray ( offset ) . writeInt8 ( key . length )
95+ offset += buffer . subarray ( offset ) . write ( key )
96+ offset += buffer . subarray ( offset ) . writeInt8 ( ix . productMetadata [ key ] . length )
97+ offset += buffer . subarray ( offset ) . write ( ix . productMetadata [ key ] )
98+ }
99+ if ( offset > 464 ) {
100+ throw new Error ( 'The metadata is too long' )
101+ }
102+ const data = buffer . subarray ( 0 , offset )
103+ return Buffer . concat ( [ discriminator , data ] )
104+ } else {
105+ const len = layout . encode ( ix , buffer )
106+ const data = buffer . subarray ( 0 , len )
107+ return Buffer . concat ( [ discriminator , data ] )
108+ }
90109 }
91110
92111 private static parseIxLayout ( idl : Idl ) : Map < string , Layout > {
@@ -114,9 +133,33 @@ export class PythOracleInstructionCoder implements InstructionCoder {
114133 if ( ! decoder ) {
115134 return null
116135 }
117- return {
118- data : decoder . layout . decode ( data ) ,
119- name : decoder . name ,
136+
137+ /// updProduct has its own format
138+ if ( decoder . name === 'updProduct' ) {
139+ const product : Product = { }
140+ let idx = 0
141+ while ( idx < data . length ) {
142+ const keyLength = data [ idx ]
143+ idx ++
144+ if ( keyLength ) {
145+ const key = data . slice ( idx , idx + keyLength ) . toString ( )
146+ idx += keyLength
147+ const valueLength = data [ idx ]
148+ idx ++
149+ const value = data . slice ( idx , idx + valueLength ) . toString ( )
150+ idx += valueLength
151+ product [ key ] = value
152+ }
153+ }
154+ return {
155+ data : product ,
156+ name : decoder . name ,
157+ }
158+ } else {
159+ return {
160+ data : decoder . layout . decode ( data ) ,
161+ name : decoder . name ,
162+ }
120163 }
121164 }
122165}
0 commit comments