PHP Algorand SDK

Hello everyone,

I’m Felipe Vieira, PHP developer and other languages.

I’m starting in the Algorand community, wonderful project, will be a pleasure develop and share solutions using this beautiful blockchain.

I created a SDK in PHP that will be the basis for my new projects, this is the first version, which will undergo updates and improvements over time, I count on everyone’s help for new improvements and I hope to help bring new projects using this language that has a huge community, feel free to use and give opinion too.

Follow the link on GitHub:

Video on Youtube:

I currently need help to create new features using the “POST /v1/transaction/sign” endpoint, I use CURL to make calls. I need to know in detail how to compose the “SignTransactionRequest”, more specifically the “transaction” field with the Pattern: "^ (?: [A-Za-z0-9 + /] {4}) * (?: [A-Za -z0-9 + /] {2} == \ | [A-Za-z0-9 + /] {3} =)? $ string (byte).

I didn’t find many details in the documentation, I tried to serialize in bytes, use msgpack, base64, etc … I’m doing something wrong.

Could someone send me an example of what this request would look like?

In my attempts it always returns the error:

[code] => 400
[message] => {
“error”: true,
“message”: “could not decode transaction”
}

I really appreciate the help,

Best Regards,

Felipe Vieira

2 Likes

Thanks for writing a PhP SDK!

It’s the base64 encoding of the msgpack-encoded Transaction object itself, but not the SignedTxn object.
The documentation needs to be updated.

Concretely, you can do the following (using jq):

$ goal clerk send --from OEOFA6R5HQA7KBQ5BGMI2B5FQ2U4S6TWF5DUEHWJ4PSYOFZ5A7LGXSM4TM --to OEOFA6R5HQA7KBQ5BGMI2B5FQ2U4S6TWF5DUEHWJ4PSYOFZ5A7LGXSM4TM --amount 1 --firstvalid 12771319 --out test.tx

$ msgpacktool -d -b32 < test.tx | jq '.txn' | msgpacktool -e -b32 > test.txforkmd

$ curl -s -H "Content-Type: application/json" -H "X-Kmd-API-Token: $(cat $ALGORAND_DATA/kmd-v0.5/kmd.token)" -X POST "$(cat $ALGORAND_DATA/kmd-v0.5/kmd.net)/v1/wallet/init" -d '{"wallet_id": "fc6a9a4570f3fe81a6a0d9a48a45f54a", "wallet_password": ""}' | jq ".wallet_handle_token" -r > wallet_token

$ WALLET_HANDLE_TOKEN=$(cat wallet_token)

$ TRANSACTION=$(base64 < test.txforkmd)

$ curl -H "Content-Type: application/json" -H "X-Kmd-API-Token: $(cat $ALGORAND_DATA/kmd-v0.5/kmd.token)" -X POST "$(cat $ALGORAND_DATA/kmd-v0.5/kmd.net)/v1/transaction/sign" -d '{"wallet_handle_token": "'"$WALLET_HANDLE_TOKEN"'","transaction": "'"$TRANSACTION"'","wallet_password": ""}'
{
  "signed_transaction": "gqNzaWfEQEOhbbpL2MfTq0fTwu9YB0LmZVsB3FR5eQGABNskF/XfOsGT/XZpQeKwamVm9d4JdokqwbMyOVWfXFsJMH1smAajdHhuiqNhbXQBo2ZlZc0D6KJmds4Awt/3o2dlbqx0ZXN0bmV0LXYxLjCiZ2jEIEhjtRiks8hOyBDyLU8QgcsPcfBZp6wg3sYvf3DlCToiomx2zgDC49+kbm90ZcQIGmpAsxfOByyjcmN2xCBxHFB6PTwB9QYdCZiNB6WGqcl6di9HQh7J4+WHFz0H1qNzbmTEIHEcUHo9PAH1Bh0JmI0HpYapyXp2L0dCHsnj5YcXPQfWpHR5cGWjcGF5"
}%

$ base64 -d <<< gqNzaWfEQEOhbbpL2MfTq0fTwu9YB0LmZVsB3FR5eQGABNskF/XfOsGT/XZpQeKwamVm9d4JdokqwbMyOVWfXFsJMH1smAajdHhuiqNhbXQBo2ZlZc0D6KJmds4Awt/3o2dlbqx0ZXN0bmV0LXYxLjCiZ2jEIEhjtRiks8hOyBDyLU8QgcsPcfBZp6wg3sYvf3DlCToiomx2zgDC49+kbm90ZcQIGmpAsxfOByyjcmN2xCBxHFB6PTwB9QYdCZiNB6WGqcl6di9HQh7J4+WHFz0H1qNzbmTEIHEcUHo9PAH1Bh0JmI0HpYapyXp2L0dCHsnj5YcXPQfWpHR5cGWjcGF5 > test.sig

The important command is:

msgpacktool -d -b32 < test.tx | jq '.txn' | msgpacktool -e -b32 > test.txforkmd

that extracts the transaction object from the SignedTxn object.

I’ve made a PR to improve the documentation:

1 Like

Hello Fabrice!

Thank you very much for the informations, I’ll try

Hi @fabrice,

Works fine with the msgpacktool, now I’m trying do using just PHP.

The REST API Already recognize the transaction now only with php, I just need to encode the addresses (snd and rcv) before encode all with Base 64, Can you help me with the specifications?

From:
snd�:DI65FPLNUXOJJR47FDTIB5TNNIA5G4EZFA44RZMRBE7AA4D453OYD2JCW4�type�pay

To: snd� =ҽm�ܔǟ(��mj�p�(9�� >p|�ݤtype�pay

stdClass Object
(
[error] => 1
[message] => key does not exist in this wallet
)

Thank you

Can you send me an example query you are doing?

Best is to debug using msgpacktool and see the difference between what you obtain by command line and what your PHP script generates.

Hi Fabrice, Sure.

Today the SDK works fine, but I’m trying to set up a CURL query only with php to create more facilities:

1- Transaction query builder

$transaction=array(
                "fee" => 1000,
                "fv" => 12435315,
                "gen" => "mainnet-v1.0",
                "gh" => "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=",
                "lv" => 12437315,
                "snd" => "DI65FPLNUXOJJR47FDTIB5TNNIA5G4EZFA44RZMRBE7AA4D453OYD2JCW4",
                "type" => "pay",
                "rcv" => "IYVZLDFIF6KUMSDFVIKHPBT3FI5QVZJKJ6BPFSGIJDUJGUUASKNRA4HUHU",
                "amt" => 1000,
);

2- Transaction Encode :

$transaction=$algorand_kmd->txn_encode($transaction);

The txn_encode() Will return msgpack and base64 encode, it working fine but, I need encode only the fields gh, snd and rcv to match the return of msgpacktool.

Return from msgpacktool (without base64):
��amt�fee��fv�� �gen�mainnet-v1.0�gh� �a�������`K�V�?m��7�� ��9$�ߢlv���note����Q� ��rcv� F+���/�FHe�w�{; �O����H�R����snd� =ҽm�ܔǟ(��mj�p�(9�� >p|�ݤtype�pay

My current return with PHP (without base64)::
��amt��fee��fv���s�gen�mainnet-v1.0�gh�,wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=�lv���C�rcv�:IYVZLDFIF6KUMSDFVIKHPBT3FI5QVZJKJ6BPFSGIJDUJGUUASKNRA4HUHU�snd�:DI65FPLNUXOJJR47FDTIB5TNNIA5G4EZFA44RZMRBE7AA4D453OYD2JCW4�type�pay

3- Build request to POST /v1/transaction/sign (JSON)

$txns=$params['params']=array(
   "transaction" => $transaction,
   "wallet_handle_token" => $wallet_handle_token,
   "wallet_password" => "testes"
);

4- Send CURL request with PHP, like:

$ curl -H "Content-Type: application/json" -H "X-Kmd-API-Token: $(cat $ALGORAND_DATA/kmd-v0.5/kmd.token)" -X POST "$(cat $ALGORAND_DATA/kmd-v0.5/kmd.net)/v1/transaction/sign" -d '$txns'

$txns contains JSON with the transaction.

I’m trying to reverse engineer but it can take a long time.

Suggestion for the REST API, create a transaction builder, ex: POST /transaction/build and already base64 encoded.

Thank you very much for your attention

1 Like

Can you print the base64 of the returns because forum does not support the characters and so we cannot copy-paste them?

Return from msgpacktool (base64):
iqNhbXQBo2ZlZc0D6KJmds4AvxUKo2dlbqxtYWlubmV0LXYxLjCiZ2jEIMBhxNj8Hb3e0tdgS+RWjj9tBBmHrDe95LYgtas5JIrfomx2zgC/GPKkbm90ZcQIlgOChlGICZ2jcmN2xCBGK5WMqC+VRkhlqhR3hnsqOwrlKk+C8sjISOiTUoCSm6NzbmTEIBo90r1tpdyUx58o5oD2bWoB03CZKDnI5ZEJPgBwfO7dpHR5cGWjcGF5

My current return with PHP (base64)::
iaNhbXTNA+ijZmVlzQPoomZ2zgC/FQqjZ2VurG1haW5uZXQtdjEuMKJnaNksd0dIRTJQd2R2ZDdTMTJCTDVGYU9QMjBFR1llc043M2t0aUMxcXpra2l0OD2ibHbOAL8Y8qNyY3bZOklZVlpMREZJRjZLVU1TREZWSUtIUEJUM0ZJNVFWWkpLSjZCUEZTR0lKRFVKR1VVQVNLTlJBNEhVSFWjc25k2TpESTY1RlBMTlVYT0pKUjQ3RkRUSUI1VE5OSUE1RzRFWkZBNDRSWk1SQkU3QUE0RDQ1M09ZRDJKQ1c0pHR5cGWjcGF5

I think I found a clue with the command line: ./msgpacktool -d -b32 < test.txforkmd

{
  "amt": 1,
  "fee": 1000,
  "fv": 12522762,
  "gen": "mainnet-v1.0",
  "gh:b32": "YBQ4JWH4DW655UWXMBF6IVUOH5WQIGMHVQ333ZFWEC22WOJERLPQ====",
  "lv": 12523762,
  "note:b32": "SYBYFBSRRAEZ2===",
  "rcv:b32": "IYVZLDFIF6KUMSDFVIKHPBT3FI5QVZJKJ6BPFSGIJDUJGUUASKNQ====",
  "snd:b32": "DI65FPLNUXOJJR47FDTIB5TNNIA5G4EZFA44RZMRBE7AA4D453OQ====",
  "type": "pay"
}

The fields gh, note, rcv, and snd has b32, maybe i have to encrypt as base32?

Your own version is:

$ echo -n "iaNhbXTNA+ijZmVlzQPoomZ2zgC/FQqjZ2VurG1haW5uZXQtdjEuMKJnaNksd0dIRTJQd2R2ZDdTMTJCTDVGYU9QMjBFR1llc043M2t0aUMxcXpra2l0OD2ibHbOAL8Y8qNyY3bZOklZVlpMREZJRjZLVU1TREZWSUtIUEJUM0ZJNVFWWkpLSjZCUEZTR0lKRFVKR1VVQVNLTlJBNEhVSFWjc25k2TpESTY1RlBMTlVYT0pKUjQ3RkRUSUI1VE5OSUE1RzRFWkZBNDRSWk1SQkU3QUE0RDQ1M09ZRDJKQ1c0pHR5cGWjcGF5" | base64 -d | msgpacktool -d -b32
{
  "amt": 1000,
  "fee": 1000,
  "fv": 12522762,
  "gen": "mainnet-v1.0",
  "gh": "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=",
  "lv": 12523762,
  "rcv": "IYVZLDFIF6KUMSDFVIKHPBT3FI5QVZJKJ6BPFSGIJDUJGUUASKNRA4HUHU",
  "snd": "DI65FPLNUXOJJR47FDTIB5TNNIA5G4EZFA44RZMRBE7AA4D453OYD2JCW4",
  "type": "pay"
}

You see 2 kinds of differences:

  1. You don’t see the suffix :b32 after gh, rcv and snd. This means that you encoded these fields as string instead of byte array. These fields must be the array of bytes corresponding to their content, not the base32/base64 corresponding string.
  2. The addresses include the checksum, while they should not. See Algorand Developer Docs for high-level and https://github.com/algorand/py-algorand-sdk/blob/8e0a83fd849e732522ff87e78337b3282ebf3629/algosdk/encoding.py#L153 how to do it concretely

Hi Fabrice!
All right! Now I got sign and create transactions using PHP only!
Your help was fundamental.
Tomorrow I will upload an SDK update with these new features.
Obrigado!

2 Likes