-
Notifications
You must be signed in to change notification settings - Fork 924
refactor(experimental): a function to compute program derived addresses #1453
Conversation
packages/addresses/LICENSE
Outdated
@@ -0,0 +1,20 @@ | |||
Copyright (c) 2018 Solana Labs, Inc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IANAL.
packages/addresses/README.md
Outdated
### `getBase58EncodedAddressFromPublicKey()` | ||
|
||
Given a public `CryptoKey`, this method will return its associated `Base58EncodedAddress`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure how this will feel in practice but in theory i like the distinction between pubkeys and addresses
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i wonder if the method name could be shorter tho, since it will be used a lot. getAddressFromPublicKey
? or maybe have a toAddress()
on the CryptoKey
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm into it. If we can agree that the commonly used thing (the base58 string) is what we mean when we say ‘address’ then we can rename all the methods for the common case, and reserve the more wordy function names for the more uncommon cases (getAddressBytesFromFoo()
etc).
I'll still keep the TypeScript types the way they are though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not necessary for this pr but when in "finishing touches" mode this is the kind of thing i personally would have a set of tests like "generate a few thousand random base addresses and seed strings and assert the old and new libraries produce the same result"
]); | ||
expect(pdaButterfly).toStrictEqual(pdaButterFly); | ||
}); | ||
// https://solana.stackexchange.com/questions/7253/what-combination-of-program-address-and-seeds-would-cause-findprogramaddress-t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hahaha i love the completionism
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noting for posterity that obvi i cant review this but clearly its third party code anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oic you're not familiar with my stacked PR workflow and you probably reviewed every commit in here. Each PR in this stack is only ‘about’ the top commit. The other commits before the last one are just there, because GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other words, wow thanks for reviewing the whole stack! :)
thank you for your service, ill try using this soon |
incidentally are we going back to not having a synchronous version of this... i know its probably something like "blah blah web workers 0.0001s speedup" but its just convenient not having pda generation infect the entire codebase with async/await, because its used so much in simple utility functions very far away on the code graph from real network calls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
programAddress: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL' as Base58EncodedAddress, | ||
seeds: [ | ||
// Owner | ||
serialize('9fYLFVoVqwH37C3dyPi6cpeobfbQ2jtLpN5HgAYDDdkm' as Base58EncodedAddress), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this return the same bytes as new PublicKey('9fYLFVoVqwH37C3dyPi6cpeobfbQ2jtLpN5HgAYDDdkm').toBuffer()
in the old lib?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does!
> new PublicKey('9fYLFVoVqwH37C3dyPi6cpeobfbQ2jtLpN5HgAYDDdkm').toBuffer()
<Buffer 80 bc fe 45 2a 9a 00 99 12 7e 5e de 0f 4f 69 98 01 18 0f a0 75 af c9 f5 df 28 ec 9b 28 c0 5d ba>
> Buffer.from(getBase58EncodedAddressCodec().serialize('9fYLFVoVqwH37C3dyPi6cpeobfbQ2jtLpN5HgAYDDdkm'))
<Buffer 80 bc fe 45 2a 9a 00 99 12 7e 5e de 0f 4f 69 98 01 18 0f a0 75 af c9 f5 df 28 ec 9b 28 c0 5d ba>
bumpSeed: 251, | ||
pda: '46v3JvPtEPeQmH3euXydEbxYD6yfxeZjWSzkkYvvM5Pp', | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of interest did you use some trick to generate these examples? Mainly asking because they all have bumpSeed 251
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generating a few addresses for the tests until exactly that is the case.
programAddress: Base58EncodedAddress; | ||
seeds: Seed[]; | ||
}>; | ||
type Seed = string | Uint8Array; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not suggesting we should keep the existing interface, but do you know how you'd convert from a Buffer
in the old code to this?
I remember that when I used Buffer.from([posX, posY])
(posX and posY are 0-255, u8 in rust) as a seed, I couldn't switch it to a Uint8Array
and get the same result in the old code
I'm not sure if the different implementation here means that new Uint8Array([posX, posY])
would be equivalent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It definitely is.
> Buffer.from([64, 216])
<Buffer 40 d8>
> new Uint8Array([64, 216])
Uint8Array(2) [ 64, 216 ]
> 0x40 === 64
true
> 0xd8 === 216
true
Buffer
has always been a pain in the ass because it's a Node-only primitive that has required a polyfill in browser, for almost no gain: #1100
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember that when I used Buffer.from([posX, posY]) (posX and posY are 0-255, u8 in rust) as a seed, I couldn't switch it to a Uint8Array and get the same result in the old code
Very sus! We should try to repro that and figure out why.
fc9ccd0
to
6afc39b
Compare
cc/ @2501babe |
ec013a2
to
45abc41
Compare
# Summary Given a program address and a series of string or bytearray seeds, this function will compute the off-chain program derived address (PDA) corresponding to both. # Test Plan ``` cd packages/addresses pnpm test:unit:browser pnpm test:unit:node ```
🎉 This PR is included in version 1.78.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Because there has been no activity on this PR for 14 days since it was merged, it has been automatically locked. Please open a new issue if it requires a follow up. |
refactor(experimental): a function to compute program derived addresses
Summary
Given a program address and a series of string or bytearray seeds, this function will compute the off-chain program derived address (PDA) corresponding to both.
Test Plan
Implements #1446.