gagliardetto / anchor-go Goto Github PK
View Code? Open in Web Editor NEWGenerate Go clients from anchor IDLs for Solana blockchain programs
License: MIT License
Generate Go clients from anchor IDLs for Solana blockchain programs
License: MIT License
hi,
thanks for your hard work, I'm trying to generate the interfaces to the jupiter.idl and i Iend up with lots of missing types.
All these structs are missing, except for SwapCrema
The interfaces were generated with the IDL from here:
https://solscan.io/account/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4#anchorProgramIdl
and the output of anchor-go was
wohlgemuth@beast:~/IdeaProjects/blockdb/blockchain/decoders/solana/idl$ anchor-go --src jupiter.json
[+] Generating client from IDL: jupiter.json
[?] idl.Events is defined, but generator is not implemented yet.
[?] idl.Errors is defined, but generator is not implemented yet.
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/instructions.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/types.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/accounts.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/Route.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/RouteWithTokenLedger.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SharedAccountsRoute.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SharedAccountsRouteWithTokenLedger.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/ExactOutRoute.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SharedAccountsExactOutRoute.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SetTokenLedger.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/CreateOpenOrders.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/CreateProgramOpenOrders.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/Claim.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/ClaimToken.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/CreateTokenLedger.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/testing_utils.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/Route_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/RouteWithTokenLedger_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SharedAccountsRoute_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SharedAccountsRouteWithTokenLedger_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/ExactOutRoute_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SharedAccountsExactOutRoute_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/SetTokenLedger_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/CreateOpenOrders_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/CreateProgramOpenOrders_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/Claim_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/ClaimToken_test.go
[✓] /home/wohlgemuth/IdeaProjects/blockdb/blockchain/decoders/solana/idl/generated/jupiter/CreateTokenLedger_test.go
Don't forget to import the necessary dependencies!
go get github.com/gagliardetto/[email protected]
go get github.com/gagliardetto/[email protected]
go get github.com/gagliardetto/[email protected]
go get github.com/gagliardetto/[email protected]
go get github.com/stretchr/[email protected]
go get github.com/davecgh/[email protected]
any idea what the issues are?
Any idea when tuple support may be coming? I have some IDLs that I'm unable to convert due to the lack of support. I'd happily offer payment for the addition of this feature and any others that may be required to convert more advanced IDLs.
Hello,
could you please provide an example how to utilize the generated IDL bindings. It's not really clear to me how to even get started with decoding a given transaction description.
thank you
i use anchor-go get the client but i have the question, just like : Error Code: InstructionFallbackNotFound. Error Number: 101. Error Message: Fallback functions are not supported
It appears the instruction in the readme is not a valid command. The readme recommends anchor idl parse -f candy-machine/program/src/lib.rs -o nft_candy_machine_v2.json
, but when I actually attempt this command, I get error: unrecognized subcommand 'parse'
. I am running anchor-cli 0.30.1
idl.json events tag not generate go struct
Currently, if the IDL lists the same name for an account and an instruction, this will produce go code in which the account name and the instruction name will be the same. For example the IDl for the token-swap program here will yield
type Swap struct {
Version uint8
IsInitialized bool
BumpSeed uint8
TokenProgramId ag_solanago.PublicKey
TokenA ag_solanago.PublicKey
TokenB ag_solanago.PublicKey
PoolMint ag_solanago.PublicKey
TokenAMint ag_solanago.PublicKey
TokenBMint ag_solanago.PublicKey
PoolFeeAccount ag_solanago.PublicKey
Fees Fees
SwapCurve SwapCurve
}
and
// Swap is the `swap` instruction.
type Swap struct {
AmountIn *uint64
MinimumAmountOut *uint64
// [0] = [] swap
//
// [1] = [] authority
//
// [2] = [SIGNER] userTransferAuthority
//
// [3] = [WRITE] source
//
// [4] = [WRITE] swapSource
//
// [5] = [WRITE] swapDestination
//
// [6] = [WRITE] destination
//
// [7] = [WRITE] poolMint
//
// [8] = [WRITE] poolFee
//
// [9] = [] tokenProgram
ag_solanago.AccountMetaSlice `bin:"-"`
}
One Possible fix can be to introduce a flag to add a custom suffix to the account struct (or the instruction struct).
In this example with a custom account suffix of Account
we would get
type SwapAccount struct {
Version uint8
IsInitialized bool
BumpSeed uint8
TokenProgramId ag_solanago.PublicKey
TokenA ag_solanago.PublicKey
TokenB ag_solanago.PublicKey
PoolMint ag_solanago.PublicKey
TokenAMint ag_solanago.PublicKey
TokenBMint ag_solanago.PublicKey
PoolFeeAccount ag_solanago.PublicKey
Fees Fees
SwapCurve SwapCurve
}
// Swap is the `swap` instruction.
type Swap struct {
AmountIn *uint64
MinimumAmountOut *uint64
// [0] = [] swap
//
// [1] = [] authority
//
// [2] = [SIGNER] userTransferAuthority
//
// [3] = [WRITE] source
//
// [4] = [WRITE] swapSource
//
// [5] = [WRITE] swapDestination
//
// [6] = [WRITE] destination
//
// [7] = [WRITE] poolMint
//
// [8] = [WRITE] poolFee
//
// [9] = [] tokenProgram
ag_solanago.AccountMetaSlice `bin:"-"`
}
Hello! I'm trying to utilize anchor-go
to generate code for some of the newer metaplex instructions.
Running into an issue with a new field they added to NFTs called CollectionDetails
.
I used shank
from metaplex to generate IDL from the token-metadata
program, and the CollectionDetails
field looks like:
{
"name": "CollectionDetails",
"type": {
"kind": "enum",
"variants": [
{
"name": "V1",
"fields": [
{
"name": "size",
"type": "u64"
}
]
}
]
}
},
Which results in the following go code generated from anchor-go
:
type CollectionDetails interface {
isCollectionDetails()
}
type collectionDetailsContainer struct {
Enum ag_binary.BorshEnum `borsh_enum:"true"`
V1 CollectionDetailsV1
}
type CollectionDetailsV1 struct {
Size uint64
}
func (obj CollectionDetailsV1) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) {
// Serialize `Size` param:
err = encoder.Encode(obj.Size)
if err != nil {
return err
}
return nil
}
func (obj *CollectionDetailsV1) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) {
// Deserialize `Size`:
err = decoder.Decode(&obj.Size)
if err != nil {
return err
}
return nil
}
func (_ *CollectionDetailsV1) isCollectionDetails() {}
Is that correct? What's the purpose of the isCollectionDetails()
function? (sorry, new to anchor)
Then in my own code i'm trying to do something like:
collectionDetails := token_metadata.CollectionDetailsV1{
Size: 0,
}
var details *token_metadata.CollectionDetails
details = &collectionDetails
And the compiler is getting upset saying that CollectionDetailsV1
can't be assigned to CollectionDetails
even tho CollectionDetailsV1
definitely implements that interface.
Any help would be greatly appreciated. Thanks so much for these libraries!
Huge fan of your Solana toolchains @gagliardetto! Could we add a serum IDL again? I found it in the history but I'm not sure why it was removed. Was it manually constructed?
Assume an IDL with this structure:
{
"version": "0.0.0",
"name": "program",
"instructions": [
"name": "bar",
"accounts": [
{
"name": "foo",
"isMut": false,
"isSigner": true
},
{
"name": "fooAccount",
"isMut": true,
"isSigner": false
}
]
]
}
As Account
is stripped from the latter name, duplicate GetFoo
and SetFoo
receiver methods are created. I'm running into this in the real world with an existing project.
Happy to contribute a fix but not sure what the solution should be. Possibilities:
Account
entirely"Allocate: account Address { address: 5VqTqhqpSRWk3zLpWnqq2N93F5gpEsfF8XEEmEtNeT9i, base: None } already in use",
It appears to me that this happens to due to Associated Account. Now it says it's already in use, but the wallet is generated new, so how could it be?
mint := solana.NewWallet()
var associatedAddress solana.PublicKey
associatedAddress, err = getAtaForMint(mint.PublicKey(), userKeyPair.PublicKey())
if err != nil {
panic(associatedAddress)
}
func getAssociatedAddress(mint solana.PublicKey, buyer solana.PublicKey) (solana.PublicKey, error) {
addr, _, err := solana.FindProgramAddress(
[][]byte{
buyer.Bytes(),
solana.TokenProgramID.Bytes(),
mint.Bytes(),
},
solana.SPLAssociatedTokenAccountProgramID,
)
fmt.Println("geT ATA: ", solana.TokenProgramID)
return addr, err
}
instructions = append(instructions,
nft_candy_machine.NewMintEeInstructionBuilder().
SetCandyMachineAccount(candyMachineAddress).
SetPayerAccount(userKeyPair.PublicKey()).
SetExpect(cm.Data.Price).
SetWalletAccount(cm.Wallet).
SetWallet2Account(wallet2).
SetTotalMintsAccount(totalMints).
SetProof(proof).
SetMintAccount(mint.PublicKey()).
SetMetadataAccount(metadataAddress).
SetMasterEditionAccount(masterEdition).
SetTokenMetadataProgramAccount(token_metadata.ProgramID).
SetTokenProgramAccount(token.ProgramID).
SetSystemProgramAccount(system.ProgramID).
SetAssociatedTokenProgramAccount(solana.SPLAssociatedTokenAccountProgramID).
SetAssociatedAccount(associatedAddress).
SetRentAccount(solana.SysVarRentPubkey).
SetClockAccount(solana.SysVarClockPubkey).
Build(),
)
My JS code I would say is 1:1 with the Go code I have here. I am not sure what I am missing out on. I am not sure if you faced this issue?
I'm getting back a weird error on my transaction --
(*solana.Transaction)(0x14000124070)(
├─ Signatures[len=1]
│ └─ 3UpnFHfN9d9ZTHsiaL2JswkFxBkzYDRHAB8CwKYdhYJQiAmuP83vYST7XKY9XMyCzd6AP7thHBjisBBBzKSYb39N
├─ Message
│ ├─ RecentBlockhash: 752C7hsnWjHbz6diYE29tm2MfeQnMA1U1w3WMSQUCzin
│ ├─ AccountKeys[len=4]
│ │ ├─ 4GBYBnYu2Nk7yP4zuNX5kpWoienPdu5TAvutLcJHf1YL
│ │ ├─ ADxdmsoW5xhtBJ44cmoPyQpvBj2rWSvgnSTS78SSBvBQ
│ │ ├─ 11111111111111111111111111111111
│ │ └─ EdUCoDdRnT5HsQ2Ejy3TWMTQP8iUyMQB4WzoNh45pNX9
│ └─ Header
│ ├─ NumRequiredSignatures: 1
│ ├─ NumReadonlySignedAccounts: 0
│ └─ NumReadonlyUnsignedAccounts: 2
└─ Instructions[len=1]
└─ Program: Worknet EdUCoDdRnT5HsQ2Ejy3TWMTQP8iUyMQB4WzoNh45pNX9
└─ Instruction: UpdateDevice
├─ Params[len=1]
│ └─ Device: (worknet.Device) {
│ Ipv4: ([4]uint8) (len=4 cap=4) {
│ 00000000 00 00 00 00 |....|
│ },
│ Hostname: (string) "",
│ Bump: (uint8) 255,
│ Status: (worknet.DeviceStatus) Registered,
│ DeviceAuthority: (solana.PublicKey) (len=32 cap=32) 4GBYBnYu2Nk7yP4zuNX5kpWoienPdu5TAvutLcJHf1YL
│ }
└─ Accounts[len=3]
├─ deviceAuthority: 4GBYBnYu2Nk7yP4zuNX5kpWoienPdu5TAvutLcJHf1YL [WRITE, SIGN]
├─ device: ADxdmsoW5xhtBJ44cmoPyQpvBj2rWSvgnSTS78SSBvBQ [WRITE]
└─ systemProgram: 11111111111111111111111111111111 []
)
daoctl: error: (*jsonrpc.RPCError)(0x14000119200)({
Code: (int) -32002,
Message: (string) (len=89) "Transaction simulation failed: Error processing Instruction 0: custom program error: 0x66",
Data: (map[string]interface {}) (len=4) {
(string) (len=8) "accounts": (interface {}) <nil>,
(string) (len=3) "err": (map[string]interface {}) (len=1) {
(string) (len=16) "InstructionError": ([]interface {}) (len=2 cap=2) {
(json.Number) (len=1) "0",
(map[string]interface {}) (len=1) {
(string) (len=6) "Custom": (json.Number) (len=3) "102"
}
}
},
(string) (len=4) "logs": ([]interface {}) (len=5 cap=8) {
(string) (len=63) "Program EdUCoDdRnT5HsQ2Ejy3TWMTQP8iUyMQB4WzoNh45pNX9 invoke [1]",
(string) (len=38) "Program log: Instruction: UpdateDevice",
(string) (len=167) "Program log: AnchorError occurred. Error Code: InstructionDidNotDeserialize. Error Number: 102. Error Message: The program could not deserialize the given instruction.",
(string) (len=90) "Program EdUCoDdRnT5HsQ2Ejy3TWMTQP8iUyMQB4WzoNh45pNX9 consumed 3587 of 200000 compute units",
(string) (len=87) "Program EdUCoDdRnT5HsQ2Ejy3TWMTQP8iUyMQB4WzoNh45pNX9 failed: custom program error: 0x66"
},
(string) (len=13) "unitsConsumed": (json.Number) (len=1) "0"
}
})
the transaction message:
(solana.Message) {
AccountKeys: ([]solana.PublicKey) (len=4 cap=4) {
(solana.PublicKey) (len=32 cap=32) 4GBYBnYu2Nk7yP4zuNX5kpWoienPdu5TAvutLcJHf1YL,
(solana.PublicKey) (len=32 cap=32) ADxdmsoW5xhtBJ44cmoPyQpvBj2rWSvgnSTS78SSBvBQ,
(solana.PublicKey) (len=32 cap=32) 11111111111111111111111111111111,
(solana.PublicKey) (len=32 cap=32) EdUCoDdRnT5HsQ2Ejy3TWMTQP8iUyMQB4WzoNh45pNX9
},
Header: (solana.MessageHeader) {
NumRequiredSignatures: (uint8) 1,
NumReadonlySignedAccounts: (uint8) 0,
NumReadonlyUnsignedAccounts: (uint8) 2
},
RecentBlockhash: (solana.Hash) (len=32 cap=32) 752C7hsnWjHbz6diYE29tm2MfeQnMA1U1w3WMSQUCzin,
Instructions: ([]solana.CompiledInstruction) (len=1 cap=1) {
(solana.CompiledInstruction) {
ProgramIDIndex: (uint16) 3,
Accounts: ([]uint16) (len=3 cap=3) {
(uint16) 0,
(uint16) 1,
(uint16) 2
},
Data: (solana.Base58) (len=58 cap=64) H9VJg8bfvmqXHgp785X5L6pv2W1DSNfH1GW48BqQ8rU8feZcSosi67B44b1oUJyW9rZrZFdaBh8DHiG
}
}
}
It's peculiar. I have the Go bindings working just fine with the RegisterDevice
instruction, which is barely different from UpdateDevice
that's throwing off the error here.
#[account]
#[derive(Default)]
pub struct Device {
pub ipv4: [u8; 4],
pub hostname: String,
pub bump: u8,
pub status: DeviceStatus,
pub device_authority: Pubkey,
}
#[derive(Accounts)]
pub struct UpdateDevice<'info> {
pub device_authority: Signer<'info>,
#[account(mut,
has_one = device_authority,
seeds = [device.device_authority.key().as_ref()],
bump,
)]
pub device: Box<Account<'info, Device>>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
#[instruction(device_authority: Pubkey)]
pub struct RegisterDevice<'info> {
#[account(mut)]
pub authority: Signer<'info>,
#[account(init,
space = 128,
seeds = [device_authority.as_ref()],
bump,
payer = authority,
)]
pub device: Box<Account<'info, Device>>,
pub system_program: Program<'info, System>,
}
My Anchor test for the same endpoint works fine 🤷
it("updates device info", async () => {
const [devicePDA, _devicePDABump] =
await anchor.web3.PublicKey.findProgramAddress(
[deviceKey.publicKey.toBuffer()],
program.programId
);
await program.methods
.updateDevice({
ipv4: [10, 10, 10, 10],
hostname: "testhost",
status: { registered: {} }, // TODO: better way to get enum?
deviceAuthority: deviceKey.publicKey,
})
.accounts({
deviceAuthority: deviceKey.publicKey,
device: devicePDA,
systemProgram: SystemProgram.programId,
})
.signers([deviceKey])
.rpc();
});
Any ideas?
If a method ends in a number "doSomething2" then the AnchorTypeIDEncoding is wrong as it treats it as do_something_2 instead of the required do_something2
I only needed to generate once so I didn't really solve this correctly as it's across multiple repos
We use an instruction that uses ctx.remaining_accounts
internally. How do we specify those remaining accounts? They're passed as a separate field in anchor.js
.
Anyone encounter the problem like this ?
anchor-go --src=./internal/wrapper/solanaclient/.json-instruction/drift_v2.json --dst=./internal/wrapper/solanaclient/generated
[+] Generating client from IDL: ./internal/wrapper/solanaclient/.json-instruction/drift_v2.json
panic: interface conversion: interface {} is string, not map[string]interface {}
goroutine 1 [running]:
main.(*IdlEnumFields).UnmarshalJSON(0x1400049b810, {0x1400035c666, 0x22, 0x1379a})
/Users/steven/go/pkg/mod/github.com/gagliardetto/[email protected]/idl.go:472 +0x21c
encoding/json.(*decodeState).array(0x1400014f568, {0x10104d660?, 0x14000456f28?, 0x137bf?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:507 +0x3ec
encoding/json.(*decodeState).value(0x1400014f568, {0x10104d660?, 0x14000456f28?, 0x6?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:364 +0x70
encoding/json.(*decodeState).object(0x1400014f568, {0x101087fc0?, 0x14000456f00?, 0x100b34a04?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:775 +0xb34
encoding/json.(*decodeState).value(0x1400014f568, {0x101087fc0?, 0x14000456f00?, 0x1?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:374 +0x40
encoding/json.(*decodeState).array(0x1400014f568, {0x1010602a0?, 0x140004770a8?, 0x137fd?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:562 +0x588
encoding/json.(*decodeState).value(0x1400014f568, {0x1010602a0?, 0x140004770a8?, 0x8?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:364 +0x70
encoding/json.(*decodeState).object(0x1400014f568, {0x1010882c0?, 0x14000477090?, 0x1382e?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:775 +0xb34
encoding/json.(*decodeState).value(0x1400014f568, {0x1010882c0?, 0x14000477090?, 0x4?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:374 +0x40
encoding/json.(*decodeState).object(0x1400014f568, {0x1010795a0?, 0x14000477080?, 0x100b34a04?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:775 +0xb34
encoding/json.(*decodeState).value(0x1400014f568, {0x1010795a0?, 0x14000477080?, 0x1b?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:374 +0x40
encoding/json.(*decodeState).array(0x1400014f568, {0x101052a00?, 0x1400024c230?, 0x3fddd?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:562 +0x588
encoding/json.(*decodeState).value(0x1400014f568, {0x101052a00?, 0x1400024c230?, 0x5?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:364 +0x70
encoding/json.(*decodeState).object(0x1400014f568, {0x10104d600?, 0x1400024c1c0?, 0x100b44edc?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:775 +0xb34
encoding/json.(*decodeState).value(0x1400014f568, {0x10104d600?, 0x1400024c1c0?, 0x100b44b90?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:374 +0x40
encoding/json.(*decodeState).unmarshal(0x1400014f568, {0x10104d600?, 0x1400024c1c0?})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/decode.go:181 +0x184
encoding/json.(*Decoder).Decode(0x1400014f540, {0x10104d600, 0x1400024c1c0})
/opt/homebrew/Cellar/[email protected]/1.20.10/libexec/src/encoding/json/stream.go:73 +0x130
main.main()
/Users/steven/go/pkg/mod/github.com/gagliardetto/[email protected]/main.go:100 +0x754
I ran into this issue using the code gen because in my Rust struct, the authority
which I used to sign a transaction was not listed as the zeroth account, which is what the Solana runtime expects for verification (since the signature is in the zeroth index of the list of sigs). So anchor-go complained about sigs, yet, it worked in the Anchor JS client.
Anchor JS bindings, I think were doing some magic behind the scenes (https://github.com/project-serum/anchor/blob/master/ts/src/program/accounts-resolver.ts#L42 ?) to make the ordering work correctly, perhaps the generated Go code could do something like this as well. But that would also probably complicate the code, so I can definitely see it as unnecessary as well.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.