mcintyre94
Repos
92
Followers
36
Following
26

Dashboard UI for run tracking/analytics

An Elixir LiveBook for simple API performance/load testing

24
1

Playground for running Python using WASM on data in the browser

16
0

Clone of the pointer anchor draw tutorial using seahorse

Events

started
Created at 2 days ago
mcintyre94 delete branch cm-blacklist
Created at 4 days ago

Blacklist eval and Function in client code

Created at 4 days ago

Fix metadata not getting saved on single file projects

Small review tweaks (#52)

  • Update explorer button wording + add shared project warning

  • Update default Seahorse code to include comment about declare_id

Add workspace icons

Move and improve shared project warning

Allow seahorse program compilation from arbitrary file names

Fix workspaces not getting saved on transition from localStorage

Minor deployment improvements

Remove borders from Text component

Refresh UI from inside the explorer class

Add validation for file system imports

Fix terminal cursor color and improve shared project warning message

Only allow .rs and .py file imports

Add error ui for new workspace

Fix xterm print function crashing when data type is not string

Parse all types into string before setting the terminal text

Move log event listener into useTerminal

Add error state for rename workspace

Fix editor not showing content when the current saved tab content is empty

Only import what's inside src folder if the imported folder has src inside

Add extra space after the last line in the editor

Add seed generation from uints

Fix program credentials not getting saved to indexeddb after change

Created at 4 days ago
Blacklist eval and Function in client code

Stops you doing evil things like console.log(eval("global" + "This" + ".pg"));

Since both of these execute code given as a string, they allow bypassing the blacklist by concatenation

Created at 4 days ago
mcintyre94 create branch cm-blacklist
Created at 4 days ago
Add keypair to the wallet interface so it can be used in client code

This PR slightly modifies the PgWallet interface to make keypair accessible.

This allows writing client code like:

const transactionSignature = await web3.sendAndConfirmTransaction(
  pg.connection,
  transaction,
  [pg.wallet.keypair]
);

This is a lot simpler than using pg.wallet.signTransaction and then sending it as a raw transaction. I think that's currently how you'd need to send a transaction?

Note that this doesn't have any security implications, client code can already run pg.wallet._kp to get at the currently private field.

If we do need to hide the keypair for security then maybe we could add _kp to the blacklisted words? But I do think it's a lot nicer to be able to access the keypair in client code if possible!

Created at 4 days ago
mcintyre94 create branch add-wallet-keypair
Created at 4 days ago

Add support for canceling, rename to SimpleScan

Add favicon, webmanifest

Created at 1 week ago
create branch
mcintyre94 create branch main
Created at 1 week ago
create repository
mcintyre94 create repository
Created at 1 week ago
mcintyre94 delete branch cm-seahorse-wasm
Created at 1 week ago
issue comment
Solana Pay message signing

Really cool to see this being worked on! One concern I have is do we want to specify whether/how apps can 'reject' a sign request?

For example if I have an NFT-gated part of my app and somebody sends the POST request in this spec, I get their public key at that point. I could look up whether they have any of my NFTs, see they don't and send back a 403 instead of letting them authenticate with that key and then having my own in-app logic to check their access afterward.

Is that a valid way for an app to behave? Or should a compliant app accept all signature requests with this scheme and only check privileges later? I think it's more obvious with browser wallets because AFAIK an app can't get in the middle of the connect flow and throw in their own checks, but this specification explicitly gives them an identity and ability to fail at that first (or second) hop.

This probably applies to transaction requests too ATM, but there are probably more use cases for "you don't have access" than "you can't perform a transaction".

Created at 2 weeks ago

Add String[N] to seahorse prelude

Add support for len() on strings

Refactor: Rename Ty::StringLength to Ty::StringOfLength

Add support for StringBytes type

This works like String, but uses a fixed N bytes instead of 4 bytes per character

Created at 2 weeks ago
Add support for strings 🧵

@ameliatastic Yep agreed - the 4 bytes per character unicode is pretty overkill for a lot of use cases.

I did a bit of experimenting and it turns out that it's not much of a change in the compiler to add StringBytes[N] which acts exactly the same but gets sized as 4 + N bytes instead. I added it in this commit: 1c861725938c3e218616c32bb8338ff1490df2bf

I don't know if we want to change the naming, but I think it's probably reasonable to have 2 types here: one for unicode and one for "I know how many bytes I want" - given how small that change was to add both. WDYT?

Created at 2 weeks ago

Add support for StringBytes type

This works like String, but uses a fixed N bytes instead of 4 bytes per character

Created at 2 weeks ago

Support creating accounts without seeds

Merge pull request #15 from mcintyre94/cm-no-seeds

Support creating accounts without seeds

Add ability to include strings of a given length

Update size on initialized accounts to add string lengths

Add String[N] to seahorse prelude

Add support for len() on strings

Refactor: Rename Ty::StringLength to Ty::StringOfLength

Created at 2 weeks ago

Hide rust warning messages when compiling

Support creating accounts without seeds

Merge pull request #13 from acheroncrypto/hide-warning-messages

Hide rust warning messages when compiling

Merge pull request #15 from mcintyre94/cm-no-seeds

Support creating accounts without seeds

Created at 2 weeks ago
delete branch
mcintyre94 delete branch cm-no-seeds
Created at 2 weeks ago
Created at 3 weeks ago
delete branch
mcintyre94 delete branch cm-guest-identity-publickey
Created at 3 weeks ago
pull request opened
Add support for strings 🧵

Note: This PR builds on #15 just to avoid conflicts. The first commit is from that PR, the rest are new

This PR adds support for strings! The end result is that we can now compile code such as:

class Tweet(Account):
  owner: Pubkey
  tweet: String[280]

@instruction
def new_tweet(author: Signer, tweet_account: Empty[Tweet], tweet: String[280]):
  tweet_account.init(payer=author, seeds = ['tweet', author])
  tweet_account.owner = author.key()

  assert len(tweet) <= 280, "Tweet must be no more than 280 characters"
  tweet_account.tweet = str(tweet)

This involves the following changes:

  • A new String[N] type is added to the compiler. In the seahorse AST this is stored as Ty::StringOfLength(len), so Seahorse always knows the maximum length of a string. In the generated Rust it is simply a String
  • When we initialize a new account, we add the length of any StringOfLength(n) fields on it to the size. This is necessary because Rust doesn't know the length of strings and std::mem::size_of::<String> is a small constant
  • The new String[N]type is added to the prelude
  • Python's len function is updated to support strings. This works slightly differently to the existing implementation for arrays, which returns the defined length. For strings we generate Rust code that computes the actual length, eg. tweet.chars().count(). This means that you can assert on the length of a string as in the example above

Note that if setting a tweet: String[N] value on an account you need to use str(tweet). This will just use the existing formatter. I've also updated the way we put string constants in Rust to add the .to_string() so you can also write tweet_account.tweet = "hello world" and it'll compile to tweet_account.tweet = "hello world!".to_string();

Also note that this will slightly over-estimate the space required for the string. I've added a comment, but because we're already doing std::mem::size_of::<Account> this includes a small number of bytes (24 in Rust playground) for the String. I'm not subtracting this from the number I calculate because I'm not sure how constant it is.

Created at 3 weeks ago

Refactor: Rename Ty::StringLength to Ty::StringOfLength

Created at 3 weeks ago

Update size on initialized accounts to add string lengths

Add String[N] to seahorse prelude

Add support for len() on strings

Created at 3 weeks ago
create branch
mcintyre94 create branch cm-support-strings
Created at 3 weeks ago
opened issue
Is there anything we can do to let an API verify the request comes from a wallet?

Opening this after seeing this SE question: https://solana.stackexchange.com/questions/2953/how-to-stop-bots-from-spamming-solana-pay-apis

Summary of that:

  • They're using Solana Pay TX requests to do gasless NFT minting, by making a signer of theirs the payer
  • It's supposed to be for a SOAP
  • Somebody created a bunch of wallets and used their API route to get the transaction and executed it themselves, draining the payer wallet and emptying the candy machine

Basically there's a use case here where the transaction shouldn't be entirely public, and they only want it to work in Solana Pay.

Currently I don't think we can really do this, the wallet just sends the public key and if you know the API you can trivially do the same. There's no obvious way to secure this, the wallet signing something with the user's private key wouldn't stop someone who owns the public key they're passing in.

The only idea I can really think of is for wallets to each generate a keypair and publish the public key. They could then sign requests and APIs could verify that it came from them using the public key. I don't like this solution though:

  • Another coordination challenge to get these keypairs generated and published, and wallets updated to sign requests
  • APIs would only support the wallets that they verified against. Could probably mitigate against this by publishing a library that checks them all similar to wallet-adapter, but still doesn't seem great
  • Would expose which wallet was used to the API, which currently won't happen unless the wallet chooses to identify itself in its request

My guess is that there's not a realistic solution here, you just need to keep the API link secret and if it's leaked then anyone can perform the transaction it produces. For most cases this is fine because the transaction has whatever costs it wants in it. But there is a limitation around things like a SOAP.

Figured I'd open an issue for discussion in case anyone has any better ideas!

Created at 3 weeks ago