anza-xyz / solana-pay Goto Github PK
View Code? Open in Web Editor NEWA new standard for decentralized payments.
Home Page: https://solanapay.com
License: Apache License 2.0
A new standard for decentralized payments.
Home Page: https://solanapay.com
License: Apache License 2.0
I'm trying to build my backend project and when I'm trying to build the files i'm getting this error:
declare module '@solana/web3.js' {
~~~~~~~
node_modules/@solana/web3.js/lib/index.d.ts:2:1
2 declare module '@solana/web3.js' {
~~~~~~~
Conflicts are in this file.
node_modules/@solana/web3.js/lib/index.d.ts:2:1 - error TS6200: Definitions of the following identifiers conflict with those in another file: Struct, Enum, SOLANA_SCHEMA, MAX_SEED_LENGTH, PublicKeyInitData, PublicKeyData, PublicKey, Account, Blockhash, BPF_LOADER_DEPRECATED_PROGRAM_ID, EpochSchedule, NONCE_ACCOUNT_LENGTH, NonceAccount, Keypair, MessageHeader, CompiledInstruction, MessageArgs, Message, TransactionSignature, AccountMeta, TransactionInstructionCtorFields, SerializeConfig, TransactionInstruction, SignaturePubkeyPair, NonceInformation, Transaction, ClientSubscriptionId, TokenAccountsFilter, Context, SendOptions, ConfirmOptions, ConfirmedSignaturesForAddress2Options, SignaturesForAddressOptions, RpcResponseAndContext, Commitment, Finality, LargestAccountsFilter, GetLargestAccountsConfig, GetSupplyConfig, SignatureStatusConfig, ContactInfo, VoteAccountInfo, VoteAccountStatus, InflationGovernor, InflationReward, EpochInfo, LeaderSchedule, Version, SimulatedTransactionAccountInfo, SimulatedTransactionResponse, ParsedInnerInstruction, TokenBalance, ParsedConfirmedTransactionMeta, ParsedTransactionMeta, CompiledInnerInstruction, ConfirmedTransactionMeta, TransactionResponse, ConfirmedTransaction, PartiallyDecodedInstruction, ParsedMessageAccount, ParsedInstruction, ParsedMessage, ParsedTransaction, ParsedConfirmedTransaction, ParsedTransactionWithMeta, BlockResponse, ConfirmedBlock, BlockSignatures, BlockProduction, GetBlockProductionConfig, PerfSample, Supply, TokenAmount, TokenAccountBalancePair, AccountBalancePair, SlotUpdate, SlotInfo, ParsedAccountData, StakeActivationData, DataSlice, MemcmpFilter, DataSizeFilter, GetProgramAccountsFilter, GetProgramAccountsConfig, GetParsedProgramAccountsConfig, GetMultipleAccountsConfig, AccountInfo, KeyedAccountInfo, AccountChangeCallback, ProgramAccountChangeCallback, SlotChangeCallback, SlotUpdateCallback, SignatureResultCallback, SignatureStatusNotification, SignatureReceivedNotification, SignatureSubscriptionCallback, SignatureSubscriptionOptions, RootChangeCallback, Logs, LogsFilter, LogsCallback, SignatureResult, TransactionError, TransactionConfirmationStatus, SignatureStatus, ConfirmedSignatureInfo, HttpHeaders, FetchMiddleware, ConnectionConfig, Connection, BPF_LOADER_PROGRAM_ID, BpfLoader, ComputeBudgetInstruction, ComputeBudgetInstructionType, RequestHeapFrameParams, ComputeBudgetProgram, CreateEd25519InstructionWithPublicKeyParams, CreateEd25519InstructionWithPrivateKeyParams, Ed25519Program, Loader, STAKE_CONFIG_ID, Authorized, Lockup, CreateStakeAccountParams, CreateStakeAccountWithSeedParams, InitializeStakeParams, DelegateStakeParams, AuthorizeStakeParams, AuthorizeWithSeedStakeParams, SplitStakeParams, SplitStakeWithSeedParams, WithdrawStakeParams, DeactivateStakeParams, MergeStakeParams, StakeInstruction, StakeInstructionType, StakeAuthorizationType, StakeAuthorizationLayout, StakeProgram, CreateAccountParams, TransferParams, AssignParams, CreateAccountWithSeedParams, CreateNonceAccountParams, CreateNonceAccountWithSeedParams, InitializeNonceParams, AdvanceNonceParams, WithdrawNonceParams, AuthorizeNonceParams, AllocateParams, AllocateWithSeedParams, AssignWithSeedParams, TransferWithSeedParams, DecodedTransferInstruction, DecodedTransferWithSeedInstruction, SystemInstruction, SystemInstructionType, SystemProgram, CreateSecp256k1InstructionWithPublicKeyParams, CreateSecp256k1InstructionWithEthAddressParams, CreateSecp256k1InstructionWithPrivateKeyParams, Secp256k1Program, PACKET_DATA_SIZE, SIGNATURE_LENGTH_IN_BYTES, VALIDATOR_INFO_KEY, Info, ValidatorInfo, VOTE_PROGRAM_ID, Lockout, EpochCredits, AuthorizedVoter, PriorVoter, BlockTimestamp, VoteAccount, VoteInit, CreateVoteAccountParams, InitializeAccountParams, AuthorizeVoteParams, WithdrawFromVoteAccountParams, VoteInstruction, VoteInstructionType, VoteAuthorizationType, VoteAuthorizationLayout, VoteProgram, SYSVAR_CLOCK_PUBKEY, SYSVAR_EPOCH_SCHEDULE_PUBKEY, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_REWARDS_PUBKEY, SYSVAR_SLOT_HASHES_PUBKEY, SYSVAR_SLOT_HISTORY_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SendTransactionError, Cluster, LAMPORTS_PER_SOL
2 declare module '@solana/web3.js' {
~~~~~~~
node_modules/@solana/pay/node_modules/@solana/web3.js/lib/index.d.ts:2:1
2 declare module '@solana/web3.js' {
~~~~~~~
Conflicts are in this file.
Found 2 errors in 2 files.
Errors Files
1 node_modules/@solana/pay/node_modules/@solana/web3.js/lib/index.d.ts:2
1 node_modules/@solana/web3.js/lib/index.d.ts:2
Is there an easier way to add icons instead of using svg files? I have tried to add some custom icons and it doesn't seem to work properly (maybe I am formatting incorrectly).
Can the Solana icon inside the QR code be changed as well?
Thanks
From the spec:
If the number of decimal places exceed what's supported for SOL (9) or the SPL token (mint specific), the wallet must reject the URL as malformed.
I noticed that the official @solana/pay
JavaScript SDK will not reject a URL with more than the maximum decimal places in amount
. It's not obvious from the spec, although it is totally understandable - it's impossible to implement this without on-chain data (at least in the SPL token case). Perhaps the spec should emphasize that this validation, both when generating and reading URLs, is the client's responsibility?
Still, regardless of the spec, there's no way for a downstream user of @solana/pay
to detect the number of decimal places provided in the URL and thus reject any which are malformed. The amount
field of ParsedURL
is encoded as a BigNumber
. That's an arbitrary-precision numerical representation, so it's possible to detect excessive nonzero digits. But as a parsing concern, these two URLs are indistinguishable:
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=123.012
solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=123.01200000000000000000000000000000000000000
It is a reasonable interpretation of the current spec to only consider nonzero digits, but considering that clients are required to validate the number of decimal places anyways, my opinion is that the second case should be explicitly forbidden.
Hi thanks for the work, could you put in the doc an example of how to integrate solana pay in a mobile app, in the doc specify that the integration between a mobile app and a mobile wallet would be through deep linking but there is no demo as if there is for integration with the web and I think it is not very clear how it is.
Is there a way to run build and deploy it to netlify or vercel just for demo purposes?
I ran into this bug when writing tests for the link-request branch. You can check out my code here. Please check out the sdk-tests branch
Error
TypeError: b must be a Uint8Array
127 |
128 | // Create an instruction to transfer native SOL
> 129 | return SystemProgram.transfer({
| ^
130 | fromPubkey: sender,
131 | toPubkey: recipient,
132 | lamports,
at checkUint8Array (node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/src/Layout.ts:149:11)
at uint8ArrayToBuffer (node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/src/Layout.ts:157:3)
at UInt.Object.<anonymous>.UInt.encode (node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/src/Layout.ts:610:5)
at Structure.encode (node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/src/Layout.ts:1311:26)
at encodeData (node_modules/@solana/web3.js/src/instruction.ts:25:15)
at Function.transfer (node_modules/@solana/web3.js/src/system-program.ts:695:14)
at createSystemInstruction (src/createTransfer.ts:129:26)
at createTransfer (src/createTransfer.ts:64:11)
at Object.<anonymous> (test/createTransfer.test.ts:62:25)
● createTransfer › should return an spl transaction
TypeError: b must be a Uint8Array
168 |
169 | // Create an instruction to transfer SPL tokens, asserting the mint and decimals match
> 170 | return createTransferCheckedInstruction(senderATA, splToken, recipientATA, sender, tokens, mint.decimals);
| ^
171 | }
172 |
at checkUint8Array (node_modules/@solana/buffer-layout/src/Layout.ts:149:11)
at uint8ArrayToBuffer (node_modules/@solana/buffer-layout/src/Layout.ts:157:3)
at UInt.encode (node_modules/@solana/buffer-layout/src/Layout.ts:588:5)
at Structure.encode (node_modules/@solana/buffer-layout/src/Layout.ts:1205:26)
at createTransferCheckedInstruction (node_modules/@solana/spl-token/src/instructions/transferChecked.ts:63:36)
at createSPLTokenInstruction (src/createTransfer.ts:170:44)
at createTransfer (src/createTransfer.ts:63:11)
at Object.<anonymous> (test/createTransfer.test.ts:74:25)
Hey all, Solana Pay looks really exciting, well done. Low-cost, low-friction IRL payments will solve a bunch of problems as we go fully cashless.
Firstly, is this the right place for this kind of question?
My question is around what's needed to build a contactless terminal for payments that feels to consumers like Apple Pay. Will wallet developers be encouraged to register the solana:
scheme so that scanning a URL in an NFC tag launches the wallet? Has anyone experimented with this, yet?
The Chinese are apparently big users of QR codes but many other nations don't really get it (yet) but do understand contactless card, phone and wearables payments. It's also easier to just wave your phone over a pad and have it do the right thing.
Cheers!
Hello! I'm trying out Solana Pay by using a forked version the point-of-sale demo, and I've found that the progress circle doesn't show up when doing Mainnet "real world" transactions.
The transactions go through correctly, but the application does not show the transaction history, or the progress circle.
Everything works as intended on Devnet however.
I would appreciate any guidance or help, and I'm willing to try to fix the issue myself if I'm pointed in the right direction, thanks!
According to the official spec we are allowed to use multiple public keys for reference, and indeed the encodeURL API from Solana Pay allows us to pass an array of public keys for this.
However, while trying to find the transaction signature - we use the getSignaturesForAddress API from Solana which expects this field to be a single public key.
Due to this, the findTransactionSignature API from Solana pay only accepts a single public key. This means that we can't effectively use multiple public keys for the reference field 😦
Is this correct? If so, the documentation need to be corrected.
I want to integrate solana pay on my apps, how can i do that?
And if possible these are the following i would prefer
In short - paypal of Crypto world with bare minimum fees
Hello! I have a question regarding transactions with SPL Tokens:
In case the recipient wallet has never been funded with an SPL Token the line referenced above would cause the very first transaction validation to fail even though the transaction actually finished successfully. Is there any reason against considering the preAmount
value 0 when no preBalance
is found ?
Thanks!
Hi team,
I am working on a Solana based NFTs project. We happen to use Saleor headless e-commerce
platform for our shop.
I think it would be great to integrate Saleor
as one of the e-commerce platform to integrate Solana Pay
with.
Let me know what you think.
Cheers
This proposal has changed. A specification and implementation now exists in #77
This is a new proposal for an extension to the Solana Pay specification.
This proposal draws in part from https://en.bitcoin.it/wiki/BIP_0072, relying on HTTPS for transmitting and authenticating arbitrary transaction payloads.
There are a some significant shortcomings of the simple BIP21-based payment link scheme described in the Solana Pay specification.
Merchants, service providers, and apps may wish to mint NFTs or transfer reward tokens with purchases, invoke programs, pay gas for customer transactions, and enable many other use cases that may be developed with arbitrary transactions.
Transactions on Solana must specify the accounts that will be included in the transaction upfront. Most useful instructions require the wallet signer address, their auxiliary token account address, etc.
This requires knowing the wallet address and being able to generate PDAs from it, which cannot be known when the link is created. In short, it's missing a sessionless "connect wallet" function.
We may expect that payment links will be maliciously or accidentally misused. Without knowing who a receiving address belongs to, it's not possible to determine from the URL who is requesting the payment.
A mechanism such as an HTTPS link allows the wallet to authenticate the source of the request. There may be other mechanisms we should consider.
I propose to add an optional request=<url-encoded-url>
query parameter to the specification.
An interactive protocol between the merchant and wallet follows:
solana:<recipient>?request=https%3A%2F%2Fmerchant.com%2Fsolanapay
Any of the parameters of the spec can also be included. <recipient>
could be considered optional. Perhaps an invalid address (e.g. a
, x
, or _
) could be provided for compatibility.
Regardless, it must not be used by the wallet if request
is provided, so providing an invalid recipient address ensures a wallet will not prompt a user to make a payment unless it can handle the request
parameter.
The customer scans the QR code and opens their wallet app.
The wallet parses link and prompts the user to make a request to https://merchant.com/solanapay
.
This is analogous to connecting a wallet to a dapp, so obtaining the user's permission is important for privacy.
https://merchant.com/solanapay?from=<wallet>&<...params>
The wallet should include any parameters from the URL provided, except for the request
parameter.
{"transaction":"<transaction>"}
The transaction
property value must be a base64-encoded serialized transaction.
The feePayer
, recentBlockhash
, nonceInfo
, and signatures
fields are optional but may be included. If they are included, the wallet must use them in the final transaction, since the transaction may be partially signed and subsidized by the merchant.
The wallet should allow additional fields in the JSON object, which may be added by future specifications.
The wallet may wish to display the domain the request came from, and may wish to show payment requests not including a request
parameter as unauthenticated.
The user signs the transaction and the wallet sends and confirms it.
The merchant discovers the transaction through the reference
parameter, if provided.
The point of sale app should probably be more robust against RPC or network errors (either from Solana or the WiFi).
Trying to import this library and use it in react-native but I get this error whenever i try to call parseURL
.
I have all other polyfills installed for react-native, so this could be an issue with the implementation of @solana/pay
.
I'll be looking into this issue on both sides in the coming week or two, but I wont be back in town for a few days so I wanted to document this here.
i have problem with complete transasic issued local host change from http://localhost:3000/ to http://localhost:3001/new?recipient= , how i can changed it back to http://localhost:3000/ after complete transasic
Generating url by encodeURL function always open FTX(blockfolio) app. Is there a way to choose app or directly create a link to open only phantom wallet app ? Thanks.
I'd like to integrate Solana Pay on my website via a button and I'd like to demo it to my team. How are people testing the start to end user flow?
I've gotten as far as a button that displays the QR code when clicked. I'm on Android and the only way I've found of scanning the qr code is with the ftx app, using real funds.
Hey guys,
Im trying to add Solana Pay in my VueJS project. I tried a lot of things, but whenever I install @solana/pay its giving this error:
* @solana/web3.js in ./node_modules/@solana/buffer-layout-utils/lib/esm/web3.mjs, ./node_modules/@solana/pay/lib/esm/constants.mjs
To install it, you can run: npm install --save @solana/web3.js
@solana/web3.js is installed I tried running it without @solana/pay and it works really good, same with @solana/spl-token, but when I install Solana Pay, @solana/spl-token also gives an error that web3.js cannot be found. I'm pretty sure that's a problem with the library. I also tried removing yarn cache, yarn.lock and reinstalling all packages.
package.json before @solana/pay installation:
{
"name": "luxnode",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"@mdi/font": "^6.5.95",
"@solana/spl-token": "^0.2.0",
"@solana/web3.js": "^1.36.0",
"axios": "^0.26.0",
"core-js": "^3.6.5",
"sass": "^1.49.8",
"sass-loader": "10",
"vue": "^2.6.11",
"vue-router": "3.5",
"vuescroll": "^4.17.3",
"vuetify": "^2.4.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.15",
"@vue/cli-plugin-router": "~4.5.15",
"@vue/cli-plugin-vuex": "~4.5.15",
"@vue/cli-service": "~4.5.15",
"sass": "~1.32.0",
"sass-loader": "^10.0.0",
"vue-cli-plugin-vuetify": "~2.4.5",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.7.0"
}
}
Hello Solana,
Thank you for making this amazing technology available to web developers around the world.
I am interested in building the WooCommerce plugin that will utilize Solana Pay. For that reason, is there a repo where I can contribute or the project is still on hold?
Thank you.
Solana's example when introducing Solana Pay was that it is possible to add an NFT to the transaction as a merchant and return it to the buyer. These could be digital copies of the product or even a receipt.
This feature is one of the most important that comes with Solana but isn't talked about in the Docs.
It would be great to have a documentation for this.
Have a great day,
Valentin.
After having followed all the steps for the merchant account and the generation of a QR code which the customer has to scan, the QR code simply does not work.
This is an example of QR code generated through the createQR
method imported from @solana/pay
Am I doing something wrong or is it a global issue?
Uncaught TypeError: fields must be array of Layout instances
at new Structure (webpack-internal:///./node_modules/@solana/pay/node_modules/@solana/buffer-layout/lib/Layout.js:1183:13)
at exports.struct (webpack-internal:///./node_modules/@solana/pay/node_modules/@solana/buffer-layout/lib/Layout.js:2862:56)
at eval (webpack-internal:///./node_modules/@solana/pay/node_modules/@solana/spl-token/lib/esm/instructions/initializeMint.mjs:23:100)
at Module../node_modules/@solana/pay/node_modules/@solana/spl-token/lib/esm/instructions/initializeMint.mjs (chunk-vendors.js:4148:1)
at __webpack_require__ (app.js:315:33)
at fn (app.js:617:21)
at eval (webpack-internal:///./node_modules/@solana/pay/node_modules/@solana/spl-token/lib/esm/instructions/index.mjs:94:77)
at Module../node_modules/@solana/pay/node_modules/@solana/spl-token/lib/esm/instructions/index.mjs (chunk-vendors.js:4102:1)
at __webpack_require__ (app.js:315:33)
at fn (app.js:617:21)
Hit error above when try to add the example code in vue example project
const testparse = async () =>{
const url =
'solana:mvines9iiHiQTysrwkJjGf2gb9Ex9jXJX8ns3qwf2kN?amount=0.01&reference=82ZJ7nbGpixjeDCmEhUcmwXYfvurzAgGdtSMuHnUgyny&label=Michael&message=Thanks%20for%20all%20the%20fish&memo=OrderId5678';
const { recipient, amount, splToken, reference, label, message, memo } = parseURL(url);
}
using packages below
"dependencies": {
"@solana/pay": "^0.1.1",
"@solana/spl-token": "^0.1.8",
"@solana/web3.js": "^1.31.0",
"bs58": "^4.0.1",
"core-js": "^3.8.3",
"tweetnacl": "^1.0.3",
"vue": "^3.2.6"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.15.1",
"@typescript-eslint/parser": "^4.15.1",
"@vue/cli-plugin-babel": "~5.0.0-beta.4",
"@vue/cli-plugin-eslint": "~5.0.0-beta.4",
"@vue/cli-plugin-typescript": "~5.0.0-beta.4",
"@vue/cli-service": "~5.0.0-beta.4",
"@vue/compiler-sfc": "^3.2.6",
"@vue/eslint-config-typescript": "^7.0.0",
"eslint": "^7.20.0",
"eslint-plugin-vue": "^7.2.0",
"stream-browserify": "^3.0.0",
"typescript": "~4.1.5"
}
Dependency (qr-code-styling
) error while trying to use the package in [email protected]
Server Error
ReferenceError: self is not defined
This error happened while generating the page. Any console logs will be displayed in the terminal window.
It's the same even if I only use the encodeURL
method.
Linking to a issue and PR for this error in their repository:
kozakdenys/qr-code-styling#38
kozakdenys/qr-code-styling#64
Hi Everyone, I was trying to use the shopify app created with solana pay for payments but there are no steps on how to integrate. So it would be great if someone can share the steps on how to do it. Thank you!
Guys pls help with poin of sale app
parcel/transformer-postcss: Failed to find '../node_modules/@solana/wallet-adapter-react-ui/styles.css' in [ /user/solana-pay/point-of-sale/src ]
Error: Failed to find '../node_modules/@solana/wallet-adapter-react-ui/styles.css'
in [
/user/solana-pay/point-of-sale/src
I was really impressed with this project.
I have a question, and if you look at the contents of "4.1 Retries" in the current solana docs, pos uses the polling strategy to check whether a transaction has been confirmed.
Is there no way to implement this as a webhook?
If there is a way, please let me know how it can be done.
I think it would be more appropriate to use a webhook rather than polling.
Hey, first of all thanks for your work!
I wanna create a store of merch on my webpage and I wanna use Solana Pay. I use React and I am trying to follow the docs and looking in the code. I created the connection and the URL but now I stuck on this point https://github.com/solana-labs/solana-pay/blob/master/core/example/payment-flow-merchant/main.ts#L46 where it says that the interaction will be handled by a wallet provider. How can we launch that interaction? In the docs I only see the QR option (https://docs.solanapay.com/core/merchant-integration#3-encode-link-into-a-qr-code) but I would like to prompt a response with the wallet, as when minting a NFT or something like that, right?
I was wondering if there are privacy issues with using Solana Pay since both the merchant and customer are now aware of each other's wallet addresses? I think this means each could peruse through the other's transaction history. Please let me know if this is already addressed somehow.
Hey guys. I am testing solana pay to build a payment module based on it but I haven't been able to successfully finalize a payment based on the payment-flow-merchant
example!
Steps that I follow:
devnet
Connection to cluster established: https://api.devnet.solana.com { 'feature-set': 3246413280, 'solana-core': '1.9.9' }
solana:GrH51Zbp6czGypTUe2gcU6B6eB9BjTERx7K6XYoXE9au?amount=0.01&reference=4ZQAj72fPDzy99UNWZdupTd5rKMeoXn7r1nguzT5hxKA&label=MORTIE-PAY&message=MORTIE-PAY%20-%20your%20order%20-%20%23001234&memo=JC%234098
Slope Wallet (Android)
while the network is set to devnet
. Transaction succeeds and gets fully confirmed. I can see the reference
and the message
added to the URL shown while approving the transaction on my wallet.findTransactionSignature()
never finds the transaction using the randomly generated reference
key. I can't actually see this transaction using the reference
on Solscan as well.Can you help me with this, please?
Should I find that reference
key somewhere in the transaction description in Solescan?
Thank you!
yarn install
installs all dependencies
yarn install
does not install dependency stream-browserify
This is easy enough to fix by running npm install stream-browserify
before running yarn start
. But maybe it should be added to the dependency list.
yarn/npm
on MacOS Monterey 12.2README.md
(commit ebe5ad9dce68dfcafd426be02ebe2e34f90cd056
)The CMS Prestashop not listed on commerce Solution.
We are Prestashop's Developpers from 12 years so we can develop the Solana Pay plugin for Prestashop if you think its a good idea to contribute to Solana Pay project ?
I realize this is a dupe of #86, but was unable to really figure out that thread. I also apologize that is probably out of the scope of this project, but figure I'd ask here anyways as I can't get into the discord as their SMS verification never works for me so I am locked out of that discord.
My question is how do we get the browser extension to popup and sign/send transactions?
For Phantom, I have followed the instructions here https://docs.phantom.app/integrating/sending-a-transaction and can get it to popup no problem.
For Solflare, I can follow their own specific code as well and get it to popup.
I'm a little confused how the solana-pay library fits into the flow with a browser extension. Let's take a use case, for example - that I want to accept SOL on my website in a variety of desktop browser extension wallets.
Would I be implementing specific code for each specific wallet? That is my assumption. To me it seems that the strength of this library is that it spits out a deep-link URL for mobile wallets. But for desktop wallets, I'm not seeing the use case.
In a perfect world, I would envision just using a library and not giving a hoot what wallet they use. That kinda seems how it is for mobile wallets that are listed (Phantom, FTX) - but not for browser wallets.
By the way, great stuff. Thanks for building this repo and thanks for putting up the sample app! Really good stuff. Again, apologies for opening this as an issue as this is more of a question.
it's my raw idea about a terminal
please share your idea and support it if you are into it
the challenges are 1-design a simple case to put the hardware together in a box and 2- an image that installs a pre-config lightweight Linux +java+solana pay.
** it can also include GUI to switch between the currency(USDC, USDT, SOL) and maybe merch
See attached file
In person POS terminal.md
Hello dear solana-pay team!
I wanted to contribute this project. Don't have any documentation for initial setup.
Please write simplest documentation for development.
Thanks @garious @oJshua @sakridge @aeyakovenko @jordansexton
I am trying to figure out how to
Not sure where to switch to mainnet at in the code, cant seem to figure out if it is in the constants.ts file or elsewhere
We propose an expansion on the Solana Pay Standard to provide an authentication standard using any crypto wallet.
There are two fundamentally different flows for a dapp to interact with a user’s wallet:
- Provider Injection: the wallet is a browser extension that injects a global object, like window.solana, which our dapp can interact with. This works best for web-apps running on a desktop browser. Mobile browsers do not currently support browser extensions (except for mobile-Safari, which added its own browser-extensions on iOS 15, although there are no crypto-wallets available yet). To get around this, MetaMask and Phantom have built browsers within their mobile apps; users visit a dapp from this in-app browser, allowing for global provider injection.
- Deep-Linking: we use the Solana URL scheme “solana:...”
to open the user’s wallet-app on their device, approve a transaction request, and then redirect back to our app or website with the response as query params. This works best for web-apps running on mobile-Safari or mobile-Chrome, within native mobile apps, and for kiosks / terminals / any app that runs on an external device. You could also remove desktop browser-extensions entirely; for example, if a dapp on my laptop needed to submit a transaction it could present me with a QR code which I could scan with my phone camera, redirect me into Phantom, and allow me to verify the transaction.
https://phantom.app/code?<params>
https://phantom.app/code?<params>
. As a last resort, we can use the Solana URL scheme ‘solana:’ and hope this routes the user somewhere useful. However the above wallet-specific url and linktree methods should always be preferred. That is, the 'solana:' URL scheme should only be used as a last resort.request=
query param to the standard, which has a URL-encoded URI to which the wallet will make a transaction request.solana:https%3A%2F%2Fmerchant.com%2Fsolanaauth?label=merchant&message=sign%20this%20please
https://phantom.app/code?request=https%3A%2F%2Fmerchant.com%2Fsolanapay&label=merchant&message=sign%20this%20please
request=
query param to the spec allows for us to use deep links.The wallet parses the link and optionally prompts the user for permission to make the request; this should be considered the same as a wallet-connect. The label and message params can optionally be displayed, but more importantly the wallet should display the url of the server to which the request will be directed. The permission step can be skipped if the wallet has connected to this domain before.
If permitted, the wallet makes a POST request to the specified url (which will be referred to as the authentication server from here on out). The label and message params will not be used again. The JSON body should have a { “account”: <pubkey> }
format
Example url: https://merchant.com/solanapay?auth=true
The authentication-server generates a nonce and a message, and then generates a challenge, which is a 3-part comma separated utf-8 string, with the format:
${origin},${nonce},${pubkey}
where origin should match the origin of the redirect URI, the nonce is a randomly generated alphanumeric string, and the pubkey is the pubkey being requested for authentication. The pubkey-portion should be considered optional in this format.
Example:
https://merchant.com,GCQLiawuDQbaaxFUAKcGpvQxfSxddZwGDp8p4Q57DfoX,17FaeoyXD2
This will be returned as a Uint8Array. The authentication server then saves the pubkey and challenge as a key-value pair, with an expiry time after which the pair will be discarded from memory. It also adds a redirect_uri and an expiry time that is an epoch time value in the future. It then returns the following (signed or unsigned)) JWT response, with this being the JSON body:
{ “message”: utf-8 string (optional),
“challenge”: <challenge> Uint8Array,
"redirect_uri": URI,
"expiry": epoch time value }
<redirect-uri>&from=<pubkey>&signature=<signature>
https://merchant.com/solanaauth?¶m1=value&from=GCQLiawuDQbaaxFUAKcGpvQxfSxddZwGDp8p4Q57DfoX&signature=<sig>
In oauth, this is called a ‘front channel communication’. A ‘back channel communication’ would be if the wallet sent the signature directly to the authentication-server, rather than including it in the redirect uri. Back channel communications are considered more secure because the two parties share an oauth credential, and if there was some piece of malicious software on the user’s device that could observe the redirect uri, that malicious software could authenticate itself before we get the chance to. However, the main point of this authentication flow is for the authentication server to place an authentication cookie in the user’s browser, so I think front channel communication is the simplest and overall best solution.
Wallets should expose a more robust method; requestAuth({ challenge: string, display?: string } ) => resp: { signature: Uint8Array }
. This method works just like signing a message, except that the wallet verifies that the challenge is not actually a transaction, and that the origin inside of the challenge is the origin of the currently connected website before it presents it to the user to sign. This adds an extra layer of security on top of the signMessage() method.
This opens up the possibility of wallets creating an 'authenticated connect' method, something Glow App is already building. The purpose is to not only get the user's pubkey, but also a proof that the user owns their pubkey as they claim. This method would be an overload of the current window.solana.connect()
method, except that the client-app provides a server-generated nonce: window.solana.connect({ nonce: string }) => resp
with the resp
object extended to contain a challenge: string
and signature: Uint8Array
param. The client-app will first fetch a nonce from the server, call the connect method supplying the nonce, and then return the response object to the server. The server will first examine the validity of the challenge-string, which is should be ${origin},${nonce},${pubkey}
, then compare that to the pubkey and signature. If it all checks out, the server will respond with an authentication token to the client.
Ideally users should be able to auto-connect and auto-authenticate in one method call, without any user interaction or permission required.
from=<pubkey>&signature=<blank>
The above has very broad applicability; even for users who have no interest in crypto, they can still use their wallet application as their preferred authentication method for any website, app, or kiosk that supports it. This greatly expands the use cases of Phantom, for example, beyond Solana. Even people with no interest in Solana could use this system.
This is a zero-knowledge authentication system, in the sense that the user does not have to share any secret information with a remote server. In contrast, when you login using a password and username you are sending that server your password in plaintext, possibly compromising your password if the server mishandles it (such as leaving it in a log file).
Furthermore, this authentication system is non-custodial, and doesn’t require the permission and service availability of a 3rd party resource-provider (such as Google or Facebook…), for either the user or the developer implementing it into their service.
One of the beauties of the oAuth / OpenId Connect standard is the ability for the client (application) to request pre-verified information about the resource-owner (user), in addition to just authenticating, which can be used to expedite purchase flows and registration flows. For example, if you’re buying a product online, you can authenticate and give the application your full shipping information in one click.
oAuth calls this a ‘scope’ request. To implement this, in the JWT response containing the server’s request, the authentication-server can add a scope parameter to the body, like:
{ scope: [name, email, shipping_address, phone_number], …}
Where each scope is a request for a specific piece of information about you. This information can be stored by your wallet or stored on-chain and encrypted using your pubkey. Your wallet app can then display a message like ‘merchant.com is requesting the following information: name, email, shipping address, and phone number’, and the user can granularly choose which pieces of information it wants to expose.
Transaction requests superseed authorization requests, because the signature for a transaction can already be used to authenticate a user. However, we can combine scopes and transactions to do some interesting things. For example, a kiosk could display a QR code, which when scanned responds with the following transaction request:
{ transaction: <transaction>,
scope: [name, email] }
This transaction could authorize the kiosk to charge us an unspecified amount within the next few minutes (after I checkout). The scope provided gives the kiosk an email address to mail the receipt to, and the name gives the restaurant owners a name to associate with my order.
In Denver there's a restaurant called Bird Call, and they have a kiosk that does exactly this with my credit card; I swipe it once and then it (1) recognizes me by name, so the restaurant employees know who to give my order to, (2) it emails me a receipt, and (3) it charges my card for however much I ordered when I checkout. I’ve seen several kiosks that now use credit cards for authentication in addition to charging for purchases, such as airport check-in kiosks.
I followed the instructions in the README
1) git clone https://github.com/solana-labs/solana-pay.git
2) cd solana-pay/point-of-sale
3) yarn install
4) yarn start
5) http://localhost:1234?recipient=caPsEFqXeu4upjqorwqhhTjmnhtob9EBUsAx7HbXpqw&label=Your+Store+Name
6) Scan QR code with Phantom iOS wallet
7) Send SOL
The SOL gets sent, I can see the transaction just fine on my phantom wallet, however, the Point of Sale app never leaves the QR code page. I am assuming it is supposed to show a spinner or a confirmation page at this point.
Thank for you for any help and apologies if I misunderstood what that PoS app is supposed to do !
Hello
I am unable to read any QR Code generated by the point-of-sale
website. I think this is my phone's issue tho. For some reason, I can't read the QR code if it has a dark background.
Left = Original
Right = Tweaked by me
The left doesn't work, but, by tweaking the colors a bit (right) my phone is able to read it.
Maybe adding some kind of Dark/Light theme switcher would be helpful for those who can't read with the dark theme :))
btw, solana pay is awesome 💪🏻
This project is going to pick up and be adopted.
So, having a framework for the OSS community to propose changes and contribute, will be great!
WDYT?
@chitalian and I are working on a Rust port of the @solana/pay
JavaScript SDK. Many float implementations, including the one in the Rust standard library and the BigNumber
library used by the official SDK, consider a leading +
to be valid when parsing numbers. We noticed that the description in the spec does not address the behavior of a leading +
character. For reference, it looks like the official SDK happens to forbid a leading +
, although it's unclear from the code whether or not it's intentional. Forbidding a leading +
feels like the correct choice, but it would be great to have that clarified in the spec.
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.