Compare commits

..

172 Commits

Author SHA1 Message Date
Maria Shodunke
36083f247a Add payment channel code snippet/tutorial 2025-07-02 11:07:14 +01:00
oeggert
71fe97fa3d Merge pull request #3162 from XRPLF/remove-portable-build
remove links to portable build from release notes
2025-06-25 14:38:48 -07:00
Rome Reginelli
928881f03d Merge pull request #3160 from XRPLF/dependabot/npm_and_yarn/_code-samples/build-a-browser-wallet/js/pbkdf2-3.1.3
Bump pbkdf2 from 3.1.2 to 3.1.3 in /_code-samples/build-a-browser-wallet/js
2025-06-25 14:23:23 -07:00
Rome Reginelli
f97f378642 Merge pull request #3151 from volodymyr-rutskyi/upgrade-realm-122
chore: update realm to 0.122.1
2025-06-25 14:13:37 -07:00
mDuo13
03dfb1f60e Upgrade dependencies 2025-06-25 14:10:39 -07:00
Oliver Eggert
9aec5a9ae8 remove links to portable build from release notes 2025-06-25 13:30:27 -07:00
Rome Reginelli
0401a21fc6 Merge pull request #3159 from XRPLF/up_mtokenauthorize
Update MPTokenAuthorize tx docs
2025-06-24 14:06:12 -07:00
Rome Reginelli
bccad295ad Merge pull request #3156 from XRPLF/rr-fix-mptokens-amendment-link
Fix MPTokensV1 amendment link
2025-06-24 14:04:42 -07:00
Rome Reginelli
a8e9273acc Merge pull request #3147 from XRPLF/dependabot/pip/_code-samples/build-a-desktop-wallet/py/requests-2.32.4
Bump requests from 2.32.0 to 2.32.4 in /_code-samples/build-a-desktop-wallet/py
2025-06-24 14:03:29 -07:00
Dennis Dawson
b2c4aa0dd2 Merge pull request #3158 from XRPLF/fix_NFT_Broker_links
Change NFT Broker links to topics rather than forms
2025-06-24 12:30:35 -07:00
oeggert
a253e654db Merge pull request #3150 from XRPLF/rippled-2.5.0
Rippled 2.5.0
2025-06-24 11:44:17 -07:00
Oliver Eggert
f3f783b07e add reviewer suggestions 2025-06-24 11:24:44 -07:00
oeggert
f9fd30ef3a Update blog/2025/rippled-2.5.0.md
Co-authored-by: Rome Reginelli <rome@ripple.com>
2025-06-24 11:15:06 -07:00
oeggert
9a1051f3cb Update blog/2025/rippled-2.5.0.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-06-24 11:14:34 -07:00
Oliver Eggert
339b70e93c update package links, commit log, and known amendments 2025-06-24 09:29:23 -07:00
Oliver Eggert
db303831af add reviewer comments 2025-06-24 09:05:56 -07:00
oeggert
8daf8f862f Merge pull request #3140 from XRPLF/xls-81
XLS-81: Permissioned DEXes
2025-06-24 09:00:40 -07:00
dependabot[bot]
6001a566c7 Bump pbkdf2 in /_code-samples/build-a-browser-wallet/js
Bumps [pbkdf2](https://github.com/crypto-browserify/pbkdf2) from 3.1.2 to 3.1.3.
- [Changelog](https://github.com/browserify/pbkdf2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crypto-browserify/pbkdf2/compare/v3.1.2...v3.1.3)

---
updated-dependencies:
- dependency-name: pbkdf2
  dependency-version: 3.1.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-24 05:04:32 +00:00
mDuo13
acc36d2081 Update MPTokenAuthorize tx docs 2025-06-23 18:04:21 -07:00
Dennis Dawson
ea0bad889a link to topics, not forms 2025-06-23 14:31:05 -07:00
Rome Reginelli
55934e03b8 Merge pull request #3157 from XRPLF/fix-account-configurator
Fix Account Configurator
2025-06-23 13:37:07 -07:00
mDuo13
1e38da684c Permissioned DEXes - port review edits from opensource 2025-06-23 13:33:44 -07:00
mDuo13
0a90236de7 Update subscription method w/ Permissioned DEXes & other fixes 2025-06-23 13:30:47 -07:00
mDuo13
7f8e251cb2 Permissioned DEX refs: fix links 2025-06-23 13:30:47 -07:00
mDuo13
a67dc50ef6 Permissioned DEX: concept, API methods, links 2025-06-23 13:30:47 -07:00
mDuo13
03370445c5 Add protocol refs for Permissioned DEXes 2025-06-23 13:30:47 -07:00
mDuo13
8604e68670 Add tx refs for PermissionedDEX 2025-06-23 13:30:47 -07:00
Oliver Eggert
2fd7b5ee75 add note about deprecated compilers 2025-06-23 13:27:37 -07:00
mDuo13
af9c7cd4a5 Fix Account Configurator
- The code samples page was glitching out because it wasn't in a
  language subfolder. Moved to a js/ folder to fix this.
- Updated pages that linked to the old location.
- The UI as linked directly in the _code-samples folder was displaying
  as expected but the JS wasn't loading correctly on the page, so none
  of the buttons worked. For now, I changed the Broker an NFT Sale
  page to link the ZIP instead.
2025-06-23 13:21:18 -07:00
oeggert
f76b364b2a Merge pull request #3155 from XRPLF/perm_dele_common_fields_2
Permission Delegation
2025-06-23 13:16:52 -07:00
Oliver Eggert
d296f07e6a fix incorrect field requirements 2025-06-23 13:13:59 -07:00
Oliver Eggert
72c0384b72 add x emoji for consistenty in delegate table 2025-06-23 13:12:11 -07:00
Oliver Eggert
d5d8df66fa clean up doc migration 2025-06-23 13:07:29 -07:00
Dennis Dawson
e0e2b63d50 Update for publication. 2025-06-23 12:48:57 -07:00
Dennis Dawson
21bf3be3af Add Delegate to common fields list 2025-06-23 12:48:49 -07:00
Dennis Dawson
451fc83deb Add Delegate to Draft Branch 2025-06-23 12:48:39 -07:00
Rome Reginelli
d3e8c8f4a0 Fix MPTokensV1 amendment link
Fix a typo causing the link to the MPTokens amendment to not be parsed correctly.
2025-06-23 12:31:55 -07:00
Oliver Eggert
88d9fce053 update blog sidebars and minor fix to release notes 2025-06-18 10:34:54 -07:00
oeggert
da60932700 Merge pull request #3138 from XRPLF/token_payment_channels_and_escrows
Updates to support tokens in payment channels and escrows
2025-06-18 10:30:43 -07:00
Dennis Dawson
8bab684cb5 Merge pull request #3122 from XRPLF/NFT_refactor
Refactor NFT code samples and update the tutorials and screenshots
2025-06-18 09:40:27 -07:00
Oliver Eggert
c1acd9e417 add batch transactions docs 2025-06-17 14:07:12 -07:00
Dennis Dawson
3ef97a1785 Update the zipped sample code. 2025-06-17 08:12:52 -07:00
Dennis Dawson
97a79550b2 Update docs/tutorials/javascript/nfts/batch-mint-nfts.md
Co-authored-by: oeggert <117319296+oeggert@users.noreply.github.com>
2025-06-17 08:10:11 -07:00
Dennis Dawson
7d84421565 Update _code-samples/nft-modular-tutorials/authorized-minter.js
Co-authored-by: oeggert <117319296+oeggert@users.noreply.github.com>
2025-06-17 07:41:48 -07:00
Dennis Dawson
fc337738e6 Update docs/tutorials/javascript/nfts/mint-and-burn-nfts.md
Co-authored-by: oeggert <117319296+oeggert@users.noreply.github.com>
2025-06-17 07:38:28 -07:00
Dennis Dawson
fc4c5262fb Update _code-samples/nft-modular-tutorials/mint-nfts.js
Co-authored-by: oeggert <117319296+oeggert@users.noreply.github.com>
2025-06-17 07:36:17 -07:00
Oliver Eggert
df89b5bd6e reorganize new features and other improvements sections 2025-06-16 20:21:46 -07:00
Oliver Eggert
532e635573 update release notes to rc2 2025-06-13 19:07:40 -07:00
Rome Reginelli
2691f7fdf9 Merge pull request #3136 from XRPLF/mvadari-patch-1
Update transaction-cost.md
2025-06-12 11:57:47 -07:00
Rome Reginelli
649e707c42 Merge pull request #3132 from egarson/patch-2
Update algorithmic-trading.md
2025-06-12 11:51:54 -07:00
Oliver Eggert
79b874cacf add additional contributors 2025-06-12 11:41:14 -07:00
Rome Reginelli
59371e02e0 Merge pull request #3153 from XRPLF/events-updates-2025-06-12
replace some existing event images, add 3 new past events
2025-06-12 11:36:49 -07:00
oeggert
fe9a9b41b1 Update blog/2025/rippled-2.5.0.md
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2025-06-12 11:30:42 -07:00
akcodez
228ff1a63e replace some existing event images, add 3 new past events 2025-06-12 11:00:11 -07:00
Aria Keshmiri
5c88b2a168 Merge pull request #3149 from XRPLF/rwa-tokenization-updates
Update RWA Tokenization documentation with new features and improved …
2025-06-12 10:41:18 -07:00
Oliver Eggert
36d785c355 add contributors 2025-06-11 12:41:04 -07:00
akcodez
8d72c91e4f rm arrows 2025-06-11 10:16:19 -07:00
akcodez
a7fd85618b qa changes 2025-06-11 10:11:59 -07:00
Vova Rutskyi
8036e2628a chore: update realm to 0.122.1 2025-06-11 17:44:56 +03:00
Mayukha Vadari
9cd10b4c44 Merge branch 'master' into mvadari-patch-1 2025-06-11 09:08:39 +08:00
Oliver Eggert
974441ff90 update notes to rc1 2025-06-10 18:07:25 -07:00
akcodez
d327c69864 Enhance light theme styles by adding color properties for section titles and utility cards. 2025-06-10 16:35:02 -07:00
akcodez
f161bd0331 adjust height of card 2025-06-10 15:17:28 -07:00
akcodez
603bcd9106 Update RWA Tokenization documentation with new features and improved descriptions; adjust CSS for better layout and responsiveness. 2025-06-10 14:39:14 -07:00
Rome Reginelli
a6b4fd1ee3 Merge pull request #3145 from XRPLF/add-temSEQ_AND_TICKET
tem-codes - add temSEQ_AND_TICKET
2025-06-10 11:50:28 -07:00
Rome Reginelli
1c3bcdd9b6 temSEQ_AND_TICKET - fix amendment name 2025-06-10 09:58:36 -07:00
Rome Reginelli
37e7f6e08e Merge pull request #3119 from XRPLF/fix_fs_dep
Fix tx-serialization JS sample code
2025-06-10 09:48:14 -07:00
Aria Keshmiri
b6473eabb9 Merge pull request #3148 from XRPLF/rm-banner
hide apex banner
2025-06-10 08:17:48 -07:00
akcodez
a603fd6b85 hide apex banner 2025-06-10 06:57:20 -07:00
dependabot[bot]
a2ae8909ea Bump requests in /_code-samples/build-a-desktop-wallet/py
Bumps [requests](https://github.com/psf/requests) from 2.32.0 to 2.32.4.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.0...v2.32.4)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.32.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-10 08:19:28 +00:00
Aria Keshmiri
1f2d6af975 Merge pull request #3146 from XRPLF/events-updates-2025-06-05
events + community page: add XRPL Core Dev Bootcamp and additional me…
2025-06-09 10:42:47 -07:00
akcodez
cf44f76240 use template literals for improved formatting. 2025-06-09 10:31:57 -07:00
akcodez
b214189e46 qa changes 2025-06-09 10:25:29 -07:00
akcodez
bb6aab25b1 Merge remote-tracking branch 'origin' into events-updates-2025-06-05 2025-06-09 08:37:35 -07:00
akcodez
ddf36ff2dd events + community page: add XRPL Core Dev Bootcamp and additional meetups, including XRPL Townhall Meeting #4 and XRP Ledger Meetup in Cannes. Introduce new images for events. 2025-06-09 08:35:58 -07:00
Maria Shodunke
3ac296c066 Merge pull request #3143 from XRPLF/vodf-accountset-rippling-flag
Add note on defaultRipple flag in Create AMM Tutorial
2025-06-09 09:25:07 +01:00
Mayukha Vadari
1bac248b31 Merge branch 'master' into mvadari-patch-1 2025-06-09 10:29:09 +08:00
Elliot.
ec4543c890 tem-codes - add temSEQ_AND_TICKET 2025-06-06 21:03:10 -07:00
Dennis Dawson
b82d397a66 fixes per Maria's review 2025-06-06 12:54:33 -07:00
Dennis Dawson
b663d36191 Update docs/tutorials/javascript/nfts/transfer-nfts.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-06-06 12:36:01 -07:00
Dennis Dawson
7eae9064f3 Update docs/tutorials/javascript/nfts/mint-and-burn-nfts.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-06-06 12:35:16 -07:00
Dennis Dawson
623a5d30a3 Update _code-samples/nft-modular-tutorials/account-support.js
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-06-06 12:34:16 -07:00
Dennis Dawson
0dc41bd569 Update _code-samples/nft-modular-tutorials/account-support.js
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-06-06 12:33:54 -07:00
Dennis Dawson
4236a9fa45 Update docs/tutorials/javascript/nfts/mint-and-burn-nfts.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-06-06 12:33:33 -07:00
Dennis Dawson
2e3e8ec794 Update docs/tutorials/javascript/nfts/mint-and-burn-nfts.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-06-06 12:33:14 -07:00
Amarantha Kulkarni
3697c919cd Merge pull request #3144 from XRPLF/update-xrplf-link
Update link to XRP Ledger Foundation
2025-06-06 07:58:17 -07:00
amarantha-k
8b4809e619 Update link to XRP Ledger Foundation 2025-06-06 07:44:33 -07:00
Maria Shodunke
1fa846e647 Add note to give some information on why defaultRipple needs to be enabled. 2025-06-06 14:41:31 +01:00
Oliver Eggert
a6743f325e initial release notes 2025-06-05 15:00:07 -07:00
Rome Reginelli
8076410c29 Merge pull request #3117 from t-ube/ja-contribute-blog
[JA] translate Contribute Blog documents
2025-06-05 13:24:20 -07:00
mDuo13
97d621f06e [EN/JA] fix blog/sidebars.yaml typo in contribution guidelines etc. 2025-06-05 13:21:42 -07:00
Dennis Dawson
7ac30a63ba Display graphic 2025-06-05 09:57:29 -07:00
Dennis Dawson
f92da3a9bd Updates to support tokens in payment channels and escrows 2025-06-03 14:23:49 -07:00
Rome Reginelli
8ca49fce23 Merge pull request #3137 from XRPLF/ka_20250603
Update Known Amendments status (2025-06-03)
2025-06-03 13:58:42 -07:00
mDuo13
841327bca5 Amendment fixes per @DennisDawson review 2025-06-03 13:50:15 -07:00
mDuo13
27a85302b1 Add 2.5.0 amendments to common links 2025-06-03 13:21:12 -07:00
mDuo13
5a9da8a1ae Known Amendments: 2025-06-03 2025-06-03 13:09:58 -07:00
Dennis Dawson
d413cc1bf7 fix broker NFTs images and links 2025-06-03 11:02:19 -07:00
Mayukha Vadari
ef40552be6 Update transaction-cost.md 2025-06-03 13:48:19 -04:00
Dennis Dawson
86ca76aa6b Merge pull request #3130 from XRPLF/fix-modular-tutorial-descriptions
Update description of modular tutorials
2025-06-02 15:38:26 -07:00
Dennis Dawson
ba47d9531e Merge pull request #3127 from XRPLF/mpt_immutability
Mention that MPT Metadata is immutable
2025-06-02 15:37:59 -07:00
Aria Keshmiri
e606c76d06 Merge pull request #3135 from XRPLF/banner-countdown-days
feat: add moment-timezone for dynamic countdown in AlertBanner component
2025-06-02 15:29:24 -07:00
akcodez
479d8b1e9a feat: add moment-timezone for dynamic countdown in AlertBanner component 2025-06-02 13:32:34 -07:00
Dennis Dawson
308779807a Merge pull request #3131 from XRPLF/gh2915_excrowFinish_Fees_update
Allow for variable fees due to a change in the base fee
2025-06-02 11:52:55 -07:00
Amarantha Kulkarni
bf85e727b5 Merge pull request #3129 from egarson/patch-1
Update peer-to-peer-payments-uc.md
2025-06-02 09:17:01 -07:00
Aria Keshmiri
5842c0176e Merge pull request #3133 from XRPLF/banner-date
feat: rm moment-timezone, use static date instead of countdown
2025-05-30 16:52:52 -07:00
akcodez
1a2d544891 rm moment-timezone, use static date instead of countdown 2025-05-30 16:38:34 -07:00
Aria Keshmiri
ddd20605da Merge pull request #3128 from XRPLF/banner-countdown 2025-05-30 15:29:48 -07:00
Edward Garson
bcf7332ae0 Update algorithmic-trading.md
Minor: Fix misleading typo
2025-05-30 10:32:43 -07:00
Dennis Dawson
5078334f95 Innocuous change to start a build 2025-05-29 13:11:20 -07:00
Dennis Dawson
f6da72a5e4 Innocuous change to kick off a build. 2025-05-29 13:04:03 -07:00
oeggert
5dcb5cb42e Merge pull request #3102 from XRPLF/permissioned-domains
Permissioned domains
2025-05-29 11:35:49 -07:00
oeggert
2fb65794c0 Update docs/tutorials/javascript/compliance/create-permissioned-domains.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-05-29 11:24:01 -07:00
oeggert
e3c6c8dda4 Update docs/tutorials/javascript/compliance/create-permissioned-domains.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-05-29 11:23:46 -07:00
oeggert
b9232fc245 Update _code-samples/modular-tutorials/credential-manager.js
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-05-29 11:23:34 -07:00
Amarantha Kulkarni
5d30328345 Merge pull request #3120 from t-ube/ja-simulate
[JA] translate Simulate documents
2025-05-29 10:44:56 -07:00
Dennis Dawson
11ad13f860 Allow for variable fees due to a change in the base fee 2025-05-29 10:21:22 -07:00
Dennis Dawson
a6573b8e29 Update description of modular tutorials 2025-05-29 09:39:19 -07:00
akcodez
b23aa3a55e Update Navbar component to use moment-timezone for countdown timer calculations 2025-05-29 09:12:30 -07:00
Edward Garson
98f8cbb9d5 Update peer-to-peer-payments-uc.md
Minor: Fix spelling and grammar errors.
2025-05-29 09:12:25 -07:00
akcodez
5c97efbdac Add moment-timezone dependency and implement countdown timer in AlertBanner component 2025-05-29 09:09:15 -07:00
Dennis Dawson
45eb02437b Mention that MPT Metadata is immutable 2025-05-29 08:54:00 -07:00
Oliver Eggert
7f80874c8e add reviewer suggestions 2025-05-28 15:39:12 -07:00
mDuo13
6d90eb4974 Fix NFTokenModify source links 2025-05-28 14:18:37 -07:00
mDuo13
9dce798703 Merge branch 'ja-dynamicnft' 2025-05-28 14:17:44 -07:00
mDuo13
d043759f72 Fix source link floating in Japanese 2025-05-28 14:12:07 -07:00
Oliver Eggert
cd539662c4 add permissioned domain modular tutorial 2025-05-28 12:59:07 -07:00
Rome Reginelli
9befa993bf Merge pull request #3125 from XRPLF/clio-release-2.4.1
Add release notes for Clio v2.4.1
2025-05-28 12:14:12 -07:00
Maria Shodunke
16c8fdd871 Add release notes for Clio v2.4.1 2025-05-28 12:43:31 +01:00
Rome Reginelli
d1648846d0 Merge pull request #3123 from t-ube/ja-freeze-kanji-to-katakana
[JA] Change freeze translation from kanji to katakana for consistency
2025-05-27 20:14:49 -07:00
Dennis Dawson
9ce8f3faae Batch mint and broker sale 2025-05-27 14:25:01 -07:00
t-ube
a27dad4cbd [JA] Change freeze translation from kanji to katakana for consistency 2025-05-27 12:31:21 +09:00
Dennis Dawson
471c2e48df add authorized minter 2025-05-23 17:06:30 -07:00
Dennis Dawson
cc10aa0f94 Update with transfer nfts. 2025-05-23 14:17:56 -07:00
Dennis Dawson
08f2fde9e4 WIP - refactoring the NFT tutorials, code, and screenshots 2025-05-23 09:54:46 -07:00
t-ube
306e169cb5 [JA] translate Simulate documents 2025-05-22 02:22:02 +09:00
Dennis Dawson
a74231ab0d improve client disconnect 2025-05-20 16:13:12 -07:00
t-ube / shirome
3afd06b23d Update @l10n/ja/resources/contribute-blog/_blog-template.md
Co-authored-by: tequ <git@tequ.dev>
2025-05-20 17:04:41 +09:00
t-ube / shirome
0eb60e6571 Update @l10n/ja/resources/contribute-blog/_blog-template.md
Co-authored-by: tequ <git@tequ.dev>
2025-05-20 17:04:34 +09:00
t-ube / shirome
72b1cdd150 Update @l10n/ja/resources/contribute-blog/_blog-template.md
Co-authored-by: tequ <git@tequ.dev>
2025-05-20 17:04:20 +09:00
Rome Reginelli
a0015990e9 Merge pull request #3112 from XRPLF/dependabot/npm_and_yarn/multi-91f5d45fea
Bump esbuild and @redocly/realm
2025-05-19 17:30:03 -07:00
mDuo13
0bef4e48c9 Fix tx-serialization JS sample code 2025-05-19 15:09:05 -07:00
Amarantha Kulkarni
f88f9d1cf0 Merge pull request #3108 from XRPLF/rr-link-mpts-from-payment
Link MPTs from Payment page
2025-05-16 13:17:37 -07:00
Amarantha Kulkarni
ec84bead02 Merge pull request #3118 from XRPLF/blog-dia-oracle
New blog post: Integrating DIA oracles on the XRP Ledger
2025-05-16 13:16:45 -07:00
amarantha-k
fbcccafb45 Minor editorial update 2025-05-16 11:29:57 -07:00
amarantha-k
f109dc8f45 Add missing image 2025-05-16 09:56:49 -07:00
amarantha-k
44e111acec Add blog post to integrate dia oracles on XRPL 2025-05-16 09:49:41 -07:00
oeggert
bdcc397433 Merge pull request #3116 from XRPLF/mvadari-patch-1
Update known-amendments.md
2025-05-15 10:32:48 -07:00
oeggert
1523837d9f Update known-amendments.md
Fix misspelling.
2025-05-15 10:31:48 -07:00
t-ube
84e8c3e241 [JA] translate Contribute Blog documents 2025-05-15 14:22:32 +09:00
Amarantha Kulkarni
f1f4004bf6 Merge pull request #3109 from XRPLF/update-amendment-status
Update the known amendment page to capture recent status updates
2025-05-14 14:03:49 -07:00
Mayukha Vadari
29bdf2210f Update known-amendments.md 2025-05-14 15:05:41 -04:00
mDuo13
d1b72a5b39 Minor tweaks to Known Amendments format 2025-05-13 18:12:10 -07:00
Rome Reginelli
ee81ed9544 Merge pull request #3110 from XRPLF/rm_legacy_links
Update/remove legacy links
2025-05-13 17:44:00 -07:00
dependabot[bot]
f00d710f32 Bump esbuild and @redocly/realm
Bumps [esbuild](https://github.com/evanw/esbuild) to 0.25.0 and updates ancestor dependency @redocly/realm. These dependencies need to be updated together.


Updates `esbuild` from 0.17.15 to 0.25.0
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2023.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.17.15...v0.25.0)

Updates `@redocly/realm` from 0.120.2 to 0.121.1

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 0.25.0
  dependency-type: indirect
- dependency-name: "@redocly/realm"
  dependency-version: 0.121.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-13 17:29:05 +00:00
Dennis Dawson
79e1612b72 Merge pull request #3091 from XRPLF/refactor_payment_modular_tuts
Revise payment tutorials, add/remove screenshots
2025-05-13 10:27:34 -07:00
Dennis Dawson
ec1f33d4e3 Merge branch 'master' into refactor_payment_modular_tuts 2025-05-13 07:31:45 -07:00
Amarantha Kulkarni
e6add92430 Merge pull request #3106 from ihomp/patch-6
Amendments: Bithomp link update
2025-05-12 13:25:23 -07:00
amarantha-k
5efad8cba7 Adding missing opening tag to fix build error 2025-05-12 13:21:02 -07:00
Rome Reginelli
8fe9041a96 Merge pull request #3111 from XRPLF/dependabot/npm_and_yarn/_code-samples/build-a-browser-wallet/js/vite-4.5.14
Bump vite from 4.5.13 to 4.5.14 in /_code-samples/build-a-browser-wallet/js
2025-05-12 13:11:16 -07:00
dependabot[bot]
49300a328f Bump vite in /_code-samples/build-a-browser-wallet/js
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.13 to 4.5.14.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.14/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.14/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 4.5.14
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-09 00:41:02 +00:00
mDuo13
4ba07466e1 Update/remove legacy links 2025-05-08 17:01:48 -07:00
amarantha-k
447b8640c8 Update amendment status 2025-05-08 13:21:37 -07:00
Rome Reginelli
559da0932c Link MPTs from Payment page
The "MPT Payments" section of this page is one of the first search results for MPTs. This seems like a place where it's useful to link back to the concept article for MPTs.
2025-05-08 09:46:57 -07:00
Dennis Dawson
c7a11da4fd Fix bad image link 2025-05-07 13:19:35 -07:00
Dennis Dawson
e57011070b change to kick off a build 2025-05-07 13:03:12 -07:00
Viacheslav Bakshaev
5f877ebd93 Bithomp link update
Changing the link from https://xrplexplorer.com/amendments to a newer https://bithomp.com/en/amendments 

Changing the name from the XRPLExplorer to Bithomp 
(re-branded back to older version)
2025-05-07 15:51:17 +02:00
tequ
a4ab945215 [JA] Add Dynamic NFTs concept and reference 2025-05-05 10:14:38 +09:00
Dennis Dawson
dba9871513 minor changes, mostly to try and kick a new build 2025-05-02 12:56:39 -07:00
Dennis Dawson
1ae3992c3a Merge branch 'master' into refactor_payment_modular_tuts 2025-05-02 12:50:46 -07:00
Dennis Dawson
b598a607a6 Updates based on feedback 2025-05-02 12:42:24 -07:00
Dennis Dawson
5bb552db12 Revise payment tutorials, add/remove screenshots 2025-04-24 10:49:20 -07:00
413 changed files with 16983 additions and 9916 deletions

View File

@@ -9,7 +9,7 @@ parent: contribute.html
## 報告する
詐欺に遭ったと思ったら、詐欺の手口や詐欺業者について、できるだけ早く、できるだけ多くの情報を集めるようにしてください。どのように行動すべきかは以下の方法を確認してください。
{% admonition type="warning" name="注意" %}誰もXRP Ledgerのアカウントを凍結したり、トランザクションを元に戻したりすることはできません。これはXRP Ledgerブロックチェーンの分散型設計によるものです。{% /admonition %}
{% admonition type="warning" name="注意" %}誰もXRP Ledgerのアカウントをフリーズしたり、トランザクションを元に戻したりすることはできません。これはXRP Ledgerブロックチェーンの分散型設計によるものです。{% /admonition %}
1. [Xrplorerの調査チーム](https://xrplorer.com/forensics/submit)に詐欺業者のウォレットアドレスを提出してください。
@@ -17,14 +17,14 @@ parent: contribute.html
2. 最寄りの警察署に通報してください。詐欺業者が捕まれば、お金を取り戻せる場合があります。
3. 詐欺業者が取引所にXRPを送金した場合は、必ず取引所のサポートチームに連絡してください。取引所は詐欺業者の口座を凍結することができます。以下は、いくつかの有名な取引所のサポートリンクです。
3. 詐欺業者が取引所にXRPを送金した場合は、必ず取引所のサポートチームに連絡してください。取引所は詐欺業者の口座をフリーズすることができます。以下は、いくつかの有名な取引所のサポートリンクです。
- [Binance](https://www.binance.com/en/support)
- [Coinbase](https://help.coinbase.com/)
- [Uphold](https://support.uphold.com/hc/en-us/requests/new)
- [Bitrue](https://www.bitrue.com/exchange-web/footer/contactus.html)
4. 詐欺業者がXRP Ledger上でXRPを他のトークンと交換した場合、そのトークンの発行者に連絡してください。発行者は[詐欺業者のトラストラインを凍結する](../docs/tutorials/how-tos/use-tokens/freeze-a-trust-line.md)ことができるかもしれません。
4. 詐欺業者がXRP Ledger上でXRPを他のトークンと交換した場合、そのトークンの発行者に連絡してください。発行者は[詐欺業者のトラストラインをフリーズする](../docs/tutorials/how-tos/use-tokens/freeze-a-trust-line.md)ことができるかもしれません。
詐欺業者の報告に関する詳細は、[Xrplorer Forensicsのヘルプ](https://xrplorer.com/forensics/help)をご覧ください。

View File

@@ -104,7 +104,7 @@ XRP Ledgerは、複数の[暗号署名アルゴリズム](#署名アルゴリズ
- マスターキーペアを無効化する。
- [凍結](../tokens/fungible-tokens/freezes.md#no-freeze)の機能を永久に放棄する。
- [フリーズ](../tokens/fungible-tokens/freezes.md#no-freeze)の機能を永久に放棄する。
- トランザクションコスト0XRPの特別な[キーリセットトランザクション](../transactions/transaction-cost.md#key-resetトランザクション)を送信する。

View File

@@ -20,7 +20,7 @@ Checksは[Escrow](escrow.md)と[Payment Channel](../../tutorials/how-tos/use-spe
* Checksではトークンを送金できます。Payment ChannelとEscrowで送金できるのはXRPのみです。
* Checksは資金を凍結しません。Payment ChannelとEscrowでは、送金元が発行したクレームでXRPが清算されるかPayment Channel、または有効期限切れまたはCrypto-conditionsによってXRPがリリースされるEscrowまでは、そのXRPを使用できません。
* Checksは資金をフリーズしません。Payment ChannelとEscrowでは、送金元が発行したクレームでXRPが清算されるかPayment Channel、または有効期限切れまたはCrypto-conditionsによってXRPがリリースされるEscrowまでは、そのXRPを使用できません。
* EscrowではXRPを自分自身に送金できます。ChecksではXRPを自身に送金することはできません。

View File

@@ -51,7 +51,7 @@ XRP Ledgerのすべての変更がそうであるように、取引を行うに
XRP Ledgerは、成行注文、指値注文、レバレッジ取引などの概念をネイティブに表現するものではありません。カスタムトークンやOfferのプロパティをクリエイティブに利用することで、いくつかは実現できるかもしれません。
分散型システムであるXRP Ledgerは、取引に関わる[アカウント](../../accounts/index.md)の背後にいる実際の人々や組織に関する情報を一切持っていません。また、ユーザや発行者は、様々な種類の裏付け資産を表すトークンの取引を規制するために、関連する法律に従う必要があります。[凍結](../fungible-tokens/freezes.md)や[認可トラストライン](../fungible-tokens/authorized-trust-lines.md)などの機能は、発行者が関連法規を順守できるよう意図しています。
分散型システムであるXRP Ledgerは、取引に関わる[アカウント](../../accounts/index.md)の背後にいる実際の人々や組織に関する情報を一切持っていません。また、ユーザや発行者は、様々な種類の裏付け資産を表すトークンの取引を規制するために、関連する法律に従う必要があります。[フリーズ](../fungible-tokens/freezes.md)や[認可トラストライン](../fungible-tokens/authorized-trust-lines.md)などの機能は、発行者が関連法規を順守できるよう意図しています。
## 関連項目

View File

@@ -46,8 +46,8 @@ Offerオブジェクトは、他のオファーやクロスカレンシー決済
- 所有者が売却する資産を一切保有しなくなった場合。
- オーナーがその資産を再度取得すると、オファーに資金が供給されるようになります。
- 売却する資産が[凍結されたトラストライン](../fungible-tokens/freezes.md)に含まれるトークンである場合。
- トラストラインが凍結解除されると、オファーは再び資金が供給されるようになります。
- 売却する資産が[フリーズされたトラストライン](../fungible-tokens/freezes.md)に含まれるトークンである場合。
- トラストラインがフリーズ解除されると、オファーは再び資金が供給されるようになります。
- オファーが新しいトラストラインを作成する必要があるが、オーナーがその[準備金](../../accounts/reserves.md)の増加に伴う十分なXRPを持っていない場合。
- オーナーが追加のXRPを調達するか、準備金の必要量が減少すると、オファーは自動的に使用可能になります。
- オファーが失効した場合。([オファーの有効期限](#オファーの有効期限)を参照)

View File

@@ -13,7 +13,7 @@ XRP Ledgerの認可トラストライン機能により、発行者は、発行
認可トラストライン機能を使用するには、発行アドレスで**RequireAuth**フラグを有効にします。その後、他のアカウントは、あなたがそのアカウントのトラストラインをあなたの発行アカウントに承認した場合にのみ、あなたが発行したトークンを保持することができます。
発行アドレスから[TrustSetトランザクション][]を送信し、自分のアカウントと認可するアカウントとの間のトラストラインを設定することで、トラストラインを認可することができます。トラストラインを認可した後、その認可を取り消すことはできません。(ただし、必要に応じてトラストラインを[凍結](freezes.md)することは可能です)。
発行アドレスから[TrustSetトランザクション][]を送信し、自分のアカウントと認可するアカウントとの間のトラストラインを設定することで、トラストラインを認可することができます。トラストラインを認可した後、その認可を取り消すことはできません。(ただし、必要に応じてトラストラインを[フリーズ](freezes.md)することは可能です)。
トラストラインを認可するためのトランザクションは、発行アドレスの署名が必要であり、残念ながらそのアドレスのリスクエクスポージャーが増加することを意味します。
@@ -116,7 +116,7 @@ POST http://localhost:8088/
- **コンセプト:**
- [Deposit Authorization](../../accounts/depositauth.md)
- [トークンの凍結](freezes.md)
- [トークンのフリーズ](freezes.md)
- **リファレンス:**
- [account_linesメソッド][]
- [account_infoメソッド][]

View File

@@ -6,29 +6,29 @@ seo:
labels:
- トークン
---
# トークンの凍結に関するよくある誤解
# トークンのフリーズに関するよくある誤解
PayPalのような中央集権的なサービスがアカウントを停止して資金にアクセスできないようにするのと同様に、Ripple社などがXRPを凍結することができるというのはよくある誤解です。XRP Ledgerには[凍結機能](freezes.md)がありますが、これは発行トークンにのみ使用可能で、XRPには使用できません。 **XRPを凍結することは誰にもできません**
PayPalのような中央集権的なサービスがアカウントを停止して資金にアクセスできないようにするのと同様に、Ripple社などがXRPをフリーズすることができるというのはよくある誤解です。XRP Ledgerには[フリーズ機能](freezes.md)がありますが、これは発行トークンにのみ使用可能で、XRPには使用できません。 **XRPをフリーズすることは誰にもできません**
XRP Ledgerのトークンは、[XRPとは根本的に異なる](../../../references/protocol/data-types/currency-formats.md#comparison)ものです。トークンは常にトラストライン上に存在し、それは凍結される可能性があります。XRPはアカウントに含まれており、凍結されることはありません。
XRP Ledgerのトークンは、[XRPとは根本的に異なる](../../../references/protocol/data-types/currency-formats.md#comparison)ものです。トークンは常にトラストライン上に存在し、それはフリーズされる可能性があります。XRPはアカウントに含まれており、フリーズされることはありません。
## XRPは単なるRipple社のトークンではないのか
いいえ、XRPはトークンとは異なります。XRPはXRP Ledger上の唯一のネイティブアセットであり、XRP Ledger上で取引を行うために必要なものです。XRPにはカウンタパーティが存在しません。つまり、誰かがXRPを保有するとき、その人は負債を保有しているのではなく、実際の通貨であるXRPを保有しているのです。この事実により、 _**<u>XRPはいかなる団体や個人によっても凍結することができません</u>**_
いいえ、XRPはトークンとは異なります。XRPはXRP Ledger上の唯一のネイティブアセットであり、XRP Ledger上で取引を行うために必要なものです。XRPにはカウンタパーティが存在しません。つまり、誰かがXRPを保有するとき、その人は負債を保有しているのではなく、実際の通貨であるXRPを保有しているのです。この事実により、 _**<u>XRPはいかなる団体や個人によってもフリーズすることができません</u>**_
## Ripple社またはXRP Ledger財団は私のトークンを凍結することができますか?
## Ripple社またはXRP Ledger財団は私のトークンをフリーズすることができますか?
XRP Ledgerは分散型であり、Ripple社やXRP Ledger財団、そして他のいかなる存在もそれをコントロールすることはできません。
あるトークンの発行者は、 _そのトークンに限定して_ あなたのトラストラインを凍結することができます。あなたのアカウントの他の部分や、異なる発行者のトークンを凍結することはできませんし、あなたがXRP Ledgerを使うのを止めることもできないのです。
あるトークンの発行者は、 _そのトークンに限定して_ あなたのトラストラインをフリーズすることができます。あなたのアカウントの他の部分や、異なる発行者のトークンをフリーズすることはできませんし、あなたがXRP Ledgerを使うのを止めることもできないのです。
さらに、トークン発行者は、トークンを凍結する能力を自主的かつ永久的に放棄することができます。この["No Freeze"](freezes.md#no-freeze)設定は、他者がトークンの使用を止めることができないという意味で、トークンがより実際の現金のように振る舞うことを想定しています。
さらに、トークン発行者は、トークンをフリーズする能力を自主的かつ永久的に放棄することができます。この["No Freeze"](freezes.md#no-freeze)設定は、他者がトークンの使用を止めることができないという意味で、トークンがより実際の現金のように振る舞うことを想定しています。
## しかし、Ripple社がJed McCaleb氏のXRPを凍結したと聞きましたが?
## しかし、Ripple社がJed McCaleb氏のXRPをフリーズしたと聞きましたが?
これは、2015年から2016年にかけて実際に起こった事件の誤報です。2013年にRipple社の創業者で同社を退社したJed McCaleb氏は、100万USドル以上のXRPをカストディ取引所であるBitstampで売却しようと試みました。Ripple社の代理人は、この売却はJed氏とRipple社が2014年に締結した契約に違反すると主張しました。Ripple社の要求により、[BitstampはJedのBitstampアカウントを凍結](https://www.coindesk.com/markets/2015/04/02/1-million-legal-fight-ensnares-ripple-bitstamp-and-jed-mccaleb/)し、裁判に持ち込まれました。この裁判は[最終的に和解](https://www.coindesk.com/markets/2016/02/12/ripple-settles-1-million-lawsuit-with-former-executive-and-founder/)となり、双方がその結果に納得したと表明しています。
これは、2015年から2016年にかけて実際に起こった事件の誤報です。2013年にRipple社の創業者で同社を退社したJed McCaleb氏は、100万USドル以上のXRPをカストディ取引所であるBitstampで売却しようと試みました。Ripple社の代理人は、この売却はJed氏とRipple社が2014年に締結した契約に違反すると主張しました。Ripple社の要求により、[BitstampはJedのBitstampアカウントをフリーズ](https://www.coindesk.com/markets/2015/04/02/1-million-legal-fight-ensnares-ripple-bitstamp-and-jed-mccaleb/)し、裁判に持ち込まれました。この裁判は[最終的に和解](https://www.coindesk.com/markets/2016/02/12/ripple-settles-1-million-lawsuit-with-former-executive-and-founder/)となり、双方がその結果に納得したと表明しています。
注目すべきは、この「凍結」はXRP Ledger上で起こったものではなく、XRP Ledgerの凍結機能を使ったものでもないことです。他のカストディアン取引所と同様に、Bitstampはユーザのアカウントを凍結し、特にそれらの資金が法的紛争に巻き込まれている場合、取引や資金の引き出しを停止する権限を持っています。
注目すべきは、この「フリーズ」はXRP Ledger上で起こったものではなく、XRP Ledgerのフリーズ機能を使ったものでもないことです。他のカストディアン取引所と同様に、Bitstampはユーザのアカウントをフリーズし、特にそれらの資金が法的紛争に巻き込まれている場合、取引や資金の引き出しを停止する権限を持っています。
一方、XRP Ledgerの[分散型取引所](../decentralized-exchange/index.md)で取引する場合は、自分で資産を管理するので、XRPの取引を止めることは誰にもできないのです。

View File

@@ -6,39 +6,39 @@ seo:
labels:
- トークン
---
# トークンの凍結
# トークンのフリーズ
発行者は発行したトークンをXRP Ledgerで凍結することができます。**これはXRP LedgerのネイティブアセットであるXRPには適用されません。**
発行者は発行したトークンをXRP Ledgerでフリーズすることができます。**これはXRP LedgerのネイティブアセットであるXRPには適用されません。**
特定のケースでは、法的要件への準拠や、疑わしい活動の調査のために、取引所またはゲートウェイが、XRP以外のトークンの残高を急きょ凍結することがあります。
特定のケースでは、法的要件への準拠や、疑わしい活動の調査のために、取引所またはゲートウェイが、XRP以外のトークンの残高を急きょフリーズすることがあります。
{% admonition type="success" name="ヒント" %}誰もXRP LedgerのXRPを凍結することはできません。しかし、カストディアル取引所は、自らの裁量で常に保管資金を凍結することができます。詳しくは、[凍結に関するよくある誤解](common-misconceptions-about-freezes.md)をご覧ください。{% /admonition %}
{% admonition type="success" name="ヒント" %}誰もXRP LedgerのXRPをフリーズすることはできません。しかし、カストディアル取引所は、自らの裁量で常に保管資金をフリーズすることができます。詳しくは、[フリーズに関するよくある誤解](common-misconceptions-about-freezes.md)をご覧ください。{% /admonition %}
凍結については、3種類の設定があります。
フリーズについては、3種類の設定があります。
* [**Individual Freeze(個別の凍結)**](#individual-freeze) - 1件の取引相手を凍結します。
* [**Global Freeze(全体の凍結)**](#global-freeze) - 取引相手全員を凍結します。
* [**No Freeze(凍結機能の放棄)**](#no-freeze) - 個々の取引相手の凍結機能と、Global Freeze機能を永久に放棄します。
* [**Individual Freeze(個別のフリーズ)**](#individual-freeze) - 1件の取引相手をフリーズします。
* [**Global Freeze(全体のフリーズ)**](#global-freeze) - 取引相手全員をフリーズします。
* [**No Freeze(フリーズ機能の放棄)**](#no-freeze) - 個々の取引相手のフリーズ機能と、Global Freeze機能を永久に放棄します。
凍結対象の残高がプラス、マイナスにかかわらず、すべての凍結設定を行うことができます。通貨イシュアーまたは通貨保持者のいずれかがトラストラインを凍結できますが、通貨保持者がイシュアーを凍結しても、その影響はわずかです。
フリーズ対象の残高がプラス、マイナスにかかわらず、すべてのフリーズ設定を行うことができます。通貨イシュアーまたは通貨保持者のいずれかがトラストラインをフリーズできますが、通貨保持者がイシュアーをフリーズしても、その影響はわずかです。
## Individual Freeze
**Individual Freeze**機能は、[トラストライン](index.md)に関する設定です。発行アドレスがIndividual Freeze設定を有効にすると、そのトラストラインの通貨に対して以下のルールが適用されます。
* 凍結されたトラストラインの両当事者間の直接決済は、凍結後も可能です。
* そのトラストラインの取引相手は、イシュアーへ直接支払う場合を除き、凍結されたトラストラインの残高を減らすことはできません。取引相手は、凍結されたイシュアンスを直接イシュアーに送信することだけが可能です。
* 取引相手は、凍結されたトラストライン上で引き続きその他の当事者からの支払を受け取ることができます。
* 取引相手が凍結されたトラストライン上のトークンの売りオファーを出した場合、[資金不足とみなされます](../decentralized-exchange/offers.md#オファーのライフサイクル)。
* フリーズされたトラストラインの両当事者間の直接決済は、フリーズ後も可能です。
* そのトラストラインの取引相手は、イシュアーへ直接支払う場合を除き、フリーズされたトラストラインの残高を減らすことはできません。取引相手は、フリーズされたイシュアンスを直接イシュアーに送信することだけが可能です。
* 取引相手は、フリーズされたトラストライン上で引き続きその他の当事者からの支払を受け取ることができます。
* 取引相手がフリーズされたトラストライン上のトークンの売りオファーを出した場合、[資金不足とみなされます](../decentralized-exchange/offers.md#オファーのライフサイクル)。
再確認: トラストラインではXRPは保持されません。XRPは凍結できません。
再確認: トラストラインではXRPは保持されません。XRPはフリーズできません。
金融機関は、疑わしい活動を行う取引相手や、金融機関の利用規約に違反する取引相手にリンクしているトラストラインを凍結できます。金融機関は、同機関が運用する、XRP Ledgerに接続されているその他のシステムにおいても、その取引相手を凍結する必要があります。(凍結しないと、アドレスから金融機関経由で支払を送金することで、望ましくない活動を行うことが依然として可能となります。)
金融機関は、疑わしい活動を行う取引相手や、金融機関の利用規約に違反する取引相手にリンクしているトラストラインをフリーズできます。金融機関は、同機関が運用する、XRP Ledgerに接続されているその他のシステムにおいても、その取引相手をフリーズする必要があります。(フリーズしないと、アドレスから金融機関経由で支払を送金することで、望ましくない活動を行うことが依然として可能となります。)
各個別アドレスは金融機関とのトラストラインを凍結できます。これは金融機関とその他のユーザの間の取引には影響しません。ただし、他のアドレス([運用アドレス](../../accounts/account-types.md)を含むからその個別アドレスに対しては、その金融機関のイシュアンスを送信できなくなります。このようなIndividual Freezeは、オファーには影響しません。
各個別アドレスは金融機関とのトラストラインをフリーズできます。これは金融機関とその他のユーザの間の取引には影響しません。ただし、他のアドレス([運用アドレス](../../accounts/account-types.md)を含むからその個別アドレスに対しては、その金融機関のイシュアンスを送信できなくなります。このようなIndividual Freezeは、オファーには影響しません。
Individual Freezeは1つの通貨にのみ適用されます。特定の取引相手の複数通貨を凍結するには、アドレスが各通貨のトラストラインで、個別にIndividual Freezeを有効にする必要があります。
Individual Freezeは1つの通貨にのみ適用されます。特定の取引相手の複数通貨をフリーズするには、アドレスが各通貨のトラストラインで、個別にIndividual Freezeを有効にする必要があります。
[No Freeze](#no-freeze)設定を有効にしている場合、アドレスはIndividual Freeze設定を有効にできません。
@@ -47,9 +47,9 @@ Individual Freezeは1つの通貨にのみ適用されます。特定の取引
**Global Freeze**機能は、アドレスに設定できます。発行アドレスがGlobal Freeze機能を有効にすると、その発行アドレスのすべてのトークンに対して以下のルールが適用されます:
* 凍結された発行アドレスのすべての取引相手は、イシュアーに直接支払う場合を除き、凍結されたアドレスへのトラストラインの残高を減らすことができません。(これはすべての[運用アドレス](../../accounts/account-types.md)にも影響します。)
* 凍結された発行アドレスの取引相手は、発行アドレスとの直接的な支払の送受信を引き続き行うことができます。
* 凍結アドレスによるトークンの売りオファーはすべて、[資金不足とみなされます](../decentralized-exchange/offers.md#オファーのライフサイクル)。
* フリーズされた発行アドレスのすべての取引相手は、イシュアーに直接支払う場合を除き、フリーズされたアドレスへのトラストラインの残高を減らすことができません。(これはすべての[運用アドレス](../../accounts/account-types.md)にも影響します。)
* フリーズされた発行アドレスの取引相手は、発行アドレスとの直接的な支払の送受信を引き続き行うことができます。
* フリーズアドレスによるトークンの売りオファーはすべて、[資金不足とみなされます](../decentralized-exchange/offers.md#オファーのライフサイクル)。
再確認: アドレスはXRPを発行できません。Global FreezeはXRPには適用されません。
@@ -57,25 +57,25 @@ Individual Freezeは1つの通貨にのみ適用されます。特定の取引
また、金融機関が新しい[発行アドレス](../../accounts/account-types.md)への移行や、営業の停止を予定している場合にも、Global Freezeを有効にすることが有用です。これにより、特定の時点で資金がロックされるため、ユーザは他の通貨で取引することができなくなります。
Global Freezeは、当該アドレスによって発行および保有されている _すべての_ 通貨に適用されます。1つの通貨のみに対してGlobal Freezeを有効にすることはできません。一部の通貨のみを凍結できるようにしたい場合は、通貨ごとに異なるアドレスを使用してください。
Global Freezeは、当該アドレスによって発行および保有されている _すべての_ 通貨に適用されます。1つの通貨のみに対してGlobal Freezeを有効にすることはできません。一部の通貨のみをフリーズできるようにしたい場合は、通貨ごとに異なるアドレスを使用してください。
アドレスのGlobal Freeze設定はいつでも有効にできます。ただし、アドレスの[No Freeze](#no-freeze)設定を有効にすると、Global Freezeを _無効にする_ ことはできません。
## No Freeze
**No Freeze**機能をアドレスに設定すると、取引相手が発行した通貨を凍結する機能を永久に放棄します。この機能を使用すれば、企業は自社が発行した資金を「物理的なお金のように」扱うことができます。これにより、企業は顧客どうしがその資金を取引することに介入できなくなります。
**No Freeze**機能をアドレスに設定すると、取引相手が発行した通貨をフリーズする機能を永久に放棄します。この機能を使用すれば、企業は自社が発行した資金を「物理的なお金のように」扱うことができます。これにより、企業は顧客どうしがその資金を取引することに介入できなくなります。
確認事項: XRPはすでに凍結できません。No Freeze機能は、XRP Ledgerで発行された他の通貨にのみ適用されます。
確認事項: XRPはすでにフリーズできません。No Freeze機能は、XRP Ledgerで発行された他の通貨にのみ適用されます。
No Freeze設定には次の2つの効果があります。
* 発行アドレスは、すべての取引相手とのトラストラインに対してIndividual Freezeを有効にできなくなります。
* 発行アドレスは、Global Freezeを有効にしてグローバル凍結を施行できますが、Global Freezeを _無効にする_ ことはできません。
* 発行アドレスは、Global Freezeを有効にしてグローバルフリーズを施行できますが、Global Freezeを _無効にする_ ことはできません。
XRP Ledgerは金融機関に対し、その発行資金が表す債務を履行することを強制できません。このため、Global Freezeを有効にする機能を放棄しても顧客を保護できません。ただし、Global Freezeを _無効にする_ 機能を放棄することで、Global Freeze機能が一部の顧客に対して不当に適用されないようにすることができます。
No Freeze設定は、アドレスに対して発行される通貨と、アドレスから発行される通貨のすべてに適用されます。一部の通貨のみを凍結できるようにしたい場合は、通貨ごとに異なるアドレスを使用してください。
No Freeze設定は、アドレスに対して発行される通貨と、アドレスから発行される通貨のすべてに適用されます。一部の通貨のみをフリーズできるようにしたい場合は、通貨ごとに異なるアドレスを使用してください。
No Freeze設定は、アドレスのマスターキーのシークレットキーにより署名されたトランザクションでのみ有効にできます。[レギュラーキー](../../../references/protocol/transactions/types/setregularkey.md)または[マルチシグトランザクション](../../accounts/multi-signing.md)を使用してNo Freezeを有効にすることはできません。
@@ -83,13 +83,13 @@ No Freeze設定は、アドレスのマスターキーのシークレットキ
# 関連項目
- [凍結コードの例](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/freeze)
- [フリーズコードの例](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/freeze)
- **コンセプト:**
- [トラストラインとトークンの発行](index.md)
- **Tutorials:**
- [No Freezeを有効化](../../../tutorials/how-tos/use-tokens/enable-no-freeze.md)
- [Global Freezeの実行](../../../tutorials/how-tos/use-tokens/enact-global-freeze.md)
- [トラストラインの凍結](../../../tutorials/how-tos/use-tokens/freeze-a-trust-line.md)
- [トラストラインのフリーズ](../../../tutorials/how-tos/use-tokens/freeze-a-trust-line.md)
- **References:**
- [account_linesメソッド][]
- [account_infoメソッド][]

View File

@@ -51,7 +51,7 @@ labels:
- **Limit**: 0から[トークンの上限量](../../../references/protocol/data-types/currency-formats.md)の範囲内の数字です。支払いや他のアカウントの操作によって、(このアカウントから見た)トラストラインの残高が限度額を超えることはできません。デフォルトは`0`です。
- **Authorized**: [Authorized Trust Lines](authorized-trust-lines.md)と併用し、このアカウントが発行するトークンを相手側に保持させることを許可するための値(true/false)です。デフォルトは`false`です。一度`true`に設定すると、元に戻すことはできません。
- **No Ripple**: トークンがこのトラストラインを通過して[ripple](rippling.md)するかどうかを設定するための値(true/false)です。デフォルトはアカウントの"Default Ripple"設定に依存します。新しいアカウントでは"Default Ripple"はoffで、つまり`true`がNo Rippleのデフォルト値となります。通常、発行者はrippleを許可し、非発行者はコミュニティクレジットのためにトラストラインを使用していない限り、rippleを無効にするべきです。
- **Freeze**: このトラストラインに[個別の凍結](freezes.md#individual-freeze)が適用されているかどうかを示す値(true/false)です。デフォルトは`false です。
- **Freeze**: このトラストラインに[個別のフリーズ](freezes.md#individual-freeze)が適用されているかどうかを示す値(true/false)です。デフォルトは`false です。
- **Quality In** および **Quality Out**: この設定により、このトラストライン上の他のアカウントで発行されたトークンを額面より少なくまたは多く評価することができます。たとえば、ステーブルコインの発行者が、オフレッジャーにある同等の資産に対してトークンの引き出しに3%の手数料を課している場合、この設定を使用して、それらのトークンを額面の97%で評価することが可能です。デフォルトは`0`で、額面価格を表しています。

View File

@@ -73,11 +73,11 @@ KYC(Know Your Customer)やAML(Anti-Money Laundering)などのコンプライア
### Freezeフラグ
保有者アカウント内のステーブルコインを凍結することができます。これは、詐欺行為が疑われる場合、または保有を強制する場合に行うことができます。個々のトラストラインを凍結することも、グローバルに凍結することもできます。
保有者アカウント内のステーブルコインをフリーズすることができます。これは、詐欺行為が疑われる場合、または保有を強制する場合に行うことができます。個々のトラストラインをフリーズすることも、グローバルにフリーズすることもできます。
逆に、トークンを凍結する能力を永久に放棄する「No Freeze」を設定することもできます。これにより、発行者がトークン同士の取引を妨害でき無くなるという意味で、そのステーブルコインはより現実の通貨に近くなります。
逆に、トークンをフリーズする能力を永久に放棄する「No Freeze」を設定することもできます。これにより、発行者がトークン同士の取引を妨害でき無くなるという意味で、そのステーブルコインはより現実の通貨に近くなります。
[トークンの凍結](../freezes.md)をご覧ください。
[トークンのフリーズ](../freezes.md)をご覧ください。
### Clawbackフラグ

View File

@@ -52,7 +52,7 @@ XRP Ledgerにおけるトークンは、[XRPと異なる性質](../../references
必要なトラストラインが設定されていれば、誰でも[Paymentトランザクション][]を送信することでトークンを発行することができます。トークンを発行者に送り返せば、トークンを「burn」することができます。また、発行者の設定により、[クロスカレンシー支払い](../payment-types/cross-currency-payments.md)やトレードでトークンをさらに生み出せるケースもあります。
発行者は、ユーザがトークンを送金する際に自動で差し引かれる「送金手数料」(transfer-fees.html)を設定することができます。発行者は、自分のトークンを含む取引レートの[ティックサイズ](decentralized-exchange/ticksize.md)を定義することもできます。発行者と一般アカウントのどちらも、トラストラインを[凍結](fungible-tokens/freezes.md)することができ、トラストライン内のトークンの使用方法を制限することができます。( XRPにはこのいずれも適用されません。)
発行者は、ユーザがトークンを送金する際に自動で差し引かれる「送金手数料」(transfer-fees.html)を設定することができます。発行者は、自分のトークンを含む取引レートの[ティックサイズ](decentralized-exchange/ticksize.md)を定義することもできます。発行者と一般アカウントのどちらも、トラストラインを[フリーズ](fungible-tokens/freezes.md)することができ、トラストライン内のトークンの使用方法を制限することができます。( XRPにはこのいずれも適用されません。)
トークン発行の技術的な手順については、[代替可能トークンの発行](../../tutorials/how-tos/use-tokens/issue-a-fungible-token.md) をご覧ください。

View File

@@ -0,0 +1,32 @@
---
seo:
description: ダイナミックNFTを作成し、URIを変更して参照されるデータオブジェクトを更新するオプションを提供します。
labels:
- 非代替性トークン, NFT
---
# ダイナミックNFT (dNFT)
標準的なNFTは変更不可能です。一部のユースケースでは、NFTの初回Mint後に参照されるデータオブジェクトを更新する機能が便利です。例えば、延期されたイベントのコンサートチケットを代替日に更新したり、スポーツ選手のバーチャルトレーディングカードを定期的に現在の統計情報に更新したりすることができます。ダイナミックNFTdNFTは、このようなユースケースに柔軟性を提供します。
## dNFTの作成
新しいNFTをミントする際に、`tfMutable`フラグ(`0x00000010`)を設定して、NFTの`URI`フィールドを更新する機能を有効にします。
## dNFTの変更
`NFTokenModify`トランザクションを使用して、dNFTの`URI`フィールドを更新します。発行者または許可された発行者の`Account`、dNFTの`Owner`(`Account`アドレスと異なる場合)、dNFTの`NFTokenID`、および新しいオブジェクトデータの`URI`を指定します。
### NFTokenModifyトランザクションの例
```json
{
"TransactionType": "NFTokenModify",
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Owner": "rogue5HnPRSszD9CWGSUz8UGHMVwSSKF6",
"Fee": "10",
"Sequence": 33,
"NFTokenID": "0008C350C182B4F213B82CCFA4C6F59AD76F0AFCFBDF04D5A048C0A300000007",
"URI": "697066733A2F2F62616679626569636D6E73347A736F6C686C6976346C746D6E356B697062776373637134616C70736D6C6179696970666B73746B736D3472746B652F5665742E706E67",
}
```

View File

@@ -46,7 +46,7 @@ _トランザクション取引_ は、XRP Ledgerを変更する唯一の
署名の種類に関係なく、あらゆるタイプのトランザクションを承認できます。ただし、次の例外があります。
* マスター秘密鍵だけが[マスター公開鍵](../../references/protocol/transactions/types/accountset.md)を無効にできます。
* マスター秘密鍵だけが[凍結機能を永続的に放棄](../tokens/fungible-tokens/freezes.md#no-freeze)できます。
* マスター秘密鍵だけが[フリーズ機能を永続的に放棄](../tokens/fungible-tokens/freezes.md#no-freeze)できます。
* アドレスからトランザクションに署名する最後の方法を削除することはできません。
マスターキーとレギュラーキーペアについて詳しくは、[暗号鍵](../accounts/cryptographic-keys.md)をご覧ください。

View File

@@ -30,7 +30,7 @@ XRPはXRP Ledgerにて使用可能な暗号通貨です。
暗号通貨は _代替可能トークン_ です。 _代替可能_ とは、あるトークンを同じ価値の他のトークンに置き換えることができるという意味です。郵便切手は代替可能相対的な価値が一致し、交換可能であるため、手紙を出すのに50セントかかる場合、25セント切手を2枚使うか、10セント切手を5枚使って郵便料金を支払うことが出来ます。
暗号通貨は分散型でもあります。通貨を管理する中央機関がないのです。一度でもトランザクションがブロックチェーンに登録されると、それを変更することはできません。暗号通貨を検閲することは困難です。システムが十分に分散化されている限り、誰もトランザクションをロールバックしたり、残高を凍結したり、誰かが分散化されたデジタル資産を使うことをブロックしたりすることはできません。あらゆる参加者の間で大きな合意がなければルールが変更されることはありません。
暗号通貨は分散型でもあります。通貨を管理する中央機関がないのです。一度でもトランザクションがブロックチェーンに登録されると、それを変更することはできません。暗号通貨を検閲することは困難です。システムが十分に分散化されている限り、誰もトランザクションをロールバックしたり、残高をフリーズしたり、誰かが分散化されたデジタル資産を使うことをブロックしたりすることはできません。あらゆる参加者の間で大きな合意がなければルールが変更されることはありません。
暗号通貨が投資家や開発者にとって魅力的なのは、単一の事業者が「電源を切って」暗号通貨を消滅させることができないからです。

View File

@@ -146,7 +146,7 @@ labels:
| `send_currencies` | 文字列の配列 | このアカウントが送金できる通貨の[通貨コード][]の配列。 |
| `validated` | ブール値 | `true`の場合、このデータは検証済みレジャーから取得されます。 |
{% admonition type="info" name="注記" %}アカウントが送金または受領できる通貨は、アカウントのトラストラインのチェックに基づいて定義されます。アカウントに通貨のトラストラインがあり、残高を増額できる余裕がある場合、その通貨を受領できます。トラストラインの残高を減らせる場合、アカウントはその通貨を送金できます。このメソッドでは、トラストラインが[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)または承認されているかどうかは確認 _されません_ 。{% /admonition %}
{% admonition type="info" name="注記" %}アカウントが送金または受領できる通貨は、アカウントのトラストラインのチェックに基づいて定義されます。アカウントに通貨のトラストラインがあり、残高を増額できる余裕がある場合、その通貨を受領できます。トラストラインの残高を減らせる場合、アカウントはその通貨を送金できます。このメソッドでは、トラストラインが[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)または承認されているかどうかは確認 _されません_ 。{% /admonition %}
## 考えられるエラー

View File

@@ -223,8 +223,8 @@ rippled account_info rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn validated
| `disallowIncomingPayChan` | 真偽値 | `true`の場合、このアカウントは第三者からの[ペイメントチャンネル](../../../../concepts/payment-types/payment-channels.md)の作成を許可していません。 _([DisallowIncoming amendment][]が必要です)_ |
| `disallowIncomingTrustline` | 真偽値 | `true`の場合、このアカウントは第三者が[トラストライン](../../../../concepts/tokens/fungible-tokens/index.md)を作ることを許可していません。 _([DisallowIncoming amendment][]が必要です)_ |
| `disallowIncomingXRP` | 真偽値 | `true`の場合、このアカウントは他者からXRPを受け取りたくありません。(これは参考情報であり、プロトコルレベルでは強制されません) |
| `globalFreeze` | 真偽値 | `true`の場合、このアカウントによって発行されたすべてのトークンは現在凍結されています。 |
| `noFreeze` | 真偽値 | `true`の場合、このアカウントは個々のトラストラインを凍結したり、グローバル凍結を行う機能を永久に放棄しています。詳細は[No Freeze](../../../../concepts/tokens/fungible-tokens/freezes.md#no-freeze)をご覧ください。 |
| `globalFreeze` | 真偽値 | `true`の場合、このアカウントによって発行されたすべてのトークンは現在フリーズされています。 |
| `noFreeze` | 真偽値 | `true`の場合、このアカウントは個々のトラストラインをフリーズしたり、グローバルフリーズを行う機能を永久に放棄しています。詳細は[No Freeze](../../../../concepts/tokens/fungible-tokens/freezes.md#no-freeze)をご覧ください。 |
| `passwordSpent` | 真偽値 | `false`の場合、このアカウントはトランザクションコスト0の特別な[キーリセットトランザクション](../../../../concepts/transactions/transaction-cost.md#key-resetトランザクション)を送信できます。プロトコルはこのフラグを自動的にオン/オフします。 |
| `requireAuthorization` | 真偽値 | `true`の場合、このアカウントは[認可トラストライン](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)を使って、発行するトークンを保持できる人を制限しています。 |
| `requireDestinationTag` | 真偽値 | `true`の場合、このアカウントは受け取るすべての支払いに[宛先タグ](../../../../tutorials/how-tos/manage-account-settings/require-destination-tags.md)をリクエストしています。 |

View File

@@ -435,8 +435,8 @@ rippled account_lines r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59
| `no_ripple_peer` | 真偽値 | (省略される場合があります)`true`の場合、ピアアカウントはこのトラストラインで[No Rippleフラグ](../../../../concepts/tokens/fungible-tokens/rippling.md)を有効にしています。もし`false`なら、このアカウントはNo Rippleフラグを無効にしていますが、このアカウントはDefault Rippleフラグも無効にしているため、[デフォルト値](../../../protocol/ledger-data/ledger-entry-types/ripplestate.md#所有者の準備金への資金供給)とはみなされません。省略された場合、そのアカウントはこのトラストラインのNo Rippleフラグが無効で、Default Rippleが有効です。{% badge href="https://github.com/XRPLF/rippled/releases/tag/1.7.0" %}更新: rippled 1.7.0{% /badge %} |
| `authorized` | 真偽値 | (省略される場合があります)このアカウントが[このトラストラインを承認した](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)場合は、`true`。省略されている場合は、`false`と同じです。 |
| `peer_authorized` | 真偽値 | (省略される場合があります)ピアアカウントが[このトラストラインを承認した](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)場合は`true`。省略されている場合は、`false`と同じです。 |
| `freeze` | 真偽値 | (省略される場合があります)このアカウントがこのトラストラインを[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)した場合は`true`。省略されている場合は、`false`と同じです。 |
| `freeze_peer` | 真偽値 | (省略される場合があります)ピアアカウントがこのトラストラインを[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)した場合は、`true`。省略されている場合は、`false`と同じです。 |
| `freeze` | 真偽値 | (省略される場合があります)このアカウントがこのトラストラインを[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)した場合は`true`。省略されている場合は、`false`と同じです。 |
| `freeze_peer` | 真偽値 | (省略される場合があります)ピアアカウントがこのトラストラインを[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)した場合は、`true`。省略されている場合は、`false`と同じです。 |
## 考えられるエラー

View File

@@ -98,7 +98,7 @@ Clioの`ledger`コマンドは、[rippledのledgerコマンド](../ledger-method
| `Field` | 値 | 説明 |
|:--------------|:------|:----------------------------------------------------|
| `owner_funds` | 文字列 | このレジャーのすべてのトランザクションの実行後に、このOfferCreateトランザクションを送信する`Account`が保有する`TakerGets`通貨の額。この通貨額が[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。 |
| `owner_funds` | 文字列 | このレジャーのすべてのトランザクションの実行後に、このOfferCreateトランザクションを送信する`Account`が保有する`TakerGets`通貨の額。この通貨額が[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。 |
リクエストで`”diff": true`を指定した場合、レスポンスにはオブジェクト`diff`が含まれます。このオブジェクトのフィールドは以下の通りです。

View File

@@ -138,7 +138,7 @@ rippled ledger current
| `Field` | 値 | 説明 |
|:--------------|:-------|:----------------------------------------------------|
| `owner_funds` | 文字列 | このレジャーのすべてのトランザクションの実行後に、このOfferCreateトランザクションを送信する`Account`が保有する`TakerGets`通貨の額。この通貨額が[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。 |
| `owner_funds` | 文字列 | このレジャーのすべてのトランザクションの実行後に、このOfferCreateトランザクションを送信する`Account`が保有する`TakerGets`通貨の額。この通貨額が[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。 |
## 考えられるエラー

View File

@@ -211,8 +211,8 @@ _([AMM amendment][]により追加されました。)_
| `amm_account` | 文字列 | AMMアカウントの[アドレス][]です。 |
| `amount` | [通貨額][] | AMMのプールにある1つの資産の合計額。(注記:リクエストに指定した`asset` _または_ `asset2`になります。) |
| `amount2` | [通貨額][] | AMMのプール内の他の資産の合計額。(注意:リクエストに指定した`asset` _または_ `asset2`になります。) |
| `asset_frozen` | 真偽値 | _(XRPの場合、省略)_ `true`の場合、`amount`の通貨は現在[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
| `asset2_frozen` | 真偽値 | _(XRPの場合、省略)_ `true`の場合、`amount2`の通貨は現在[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
| `asset_frozen` | 真偽値 | _(XRPの場合、省略)_ `true`の場合、`amount`の通貨は現在[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
| `asset2_frozen` | 真偽値 | _(XRPの場合、省略)_ `true`の場合、`amount2`の通貨は現在[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
| `auction_slot` | オブジェクト | _(省略される場合があります)_ 存在する場合、現在のオークションスロットの所有者を記述した[オークションスロットオブジェクト](#オークションスロットオブジェクト)です。 |
| `lp_token` | [通貨額][] | このAMMのLPトークンの発行残高の合計。リクエスト時に`account`フィールドで流動性プロバイダを指定した場合、その流動性プロバイダが保有するこのAMMのLPトークンの量です。 |
| `trading_fee` | 数値 | AMMの現在の取引手数料。単位は1/100,000で、1は0.001%の手数料に相当します。 |

View File

@@ -563,7 +563,7 @@ labels:
| `Field` | 値 | 説明 |
| :------------------------ | :----- | ---- |
| `transaction.owner_funds` | 文字列 | このOfferCreateトランザクションを送信する`Account`が、このトランザクション実行後に有する`TakerGets`通貨の金額。この通貨額が[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。<br>[API v2][]では`tx_json.owner_funds`に変更されました。 |
| `transaction.owner_funds` | 文字列 | このOfferCreateトランザクションを送信する`Account`が、このトランザクション実行後に有する`TakerGets`通貨の金額。この通貨額が[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。<br>[API v2][]では`tx_json.owner_funds`に変更されました。 |
## Book Changesストリーム

View File

@@ -0,0 +1,192 @@
---
seo:
description: あらゆる種類のトランザクションを仮実行して、結果とメタデータをプレビューします。
labels:
- トランザクション送信
---
# simulate
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/rpc/handlers/Simulate.cpp "ソース")
`simulate` メソッドは、あらゆる トランザクションを仮実行し、XRP Ledger に反映することなく、その結果やメタデータを事前に確認できます。このコマンドはネットワークにトランザクションを送信しないため、手数料は発生しません。
{% admonition type="warning" name="Caution" %}
`simulate` メソッドの結果は、実際にトランザクションを送信したときと同じになるとは限りません。これは、トランザクションの処理に影響する台帳の状態が、シミュレーションと送信の間に変化する可能性があるためです。
{% /admonition %}
## リクエストのフォーマット
リクエストのフォーマットの例:
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"id": 2,
"command": "simulate",
"tx_json" : {
"TransactionType" : "Payment",
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Destination" : "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Amount" : {
"currency" : "USD",
"value" : "1",
"issuer" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"
}
}
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"method": "simulate",
"params": {
"tx_json" : {
"TransactionType" : "Payment",
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Destination" : "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Amount" : {
"currency" : "USD",
"value" : "1",
"issuer" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"
}
}
}
}
```
{% /tab %}
{% /tabs %}
{% try-it method="simulate" /%}
リクエストには以下のパラメーターが含まれます。
| フィールド | 型 | 必須? | 説明 |
| --------- | ------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `tx_blob` | 文字列 | はい | シミュレーション対象のトランザクションを[バイナリフォーマット](https://xrpl.org/ja/docs/references/protocol/binary-format)で指定します。このフィールドを使用する場合、`tx_json`は同時に指定しないでください。 |
| `tx_json` | オブジェクト | はい | シミュレーション対象のトランザクションをJSON形式で指定します。このフィールドを使用する場合は、`tx_blob`を同時に指定しないでください。 |
| `binary` | ブール値 | いいえ | デフォルト値は`false`であり、この場合はデータとメタデータがJSON形式で返されます。`true`を指定すると、データとメタデータはバイナリフォーマットで返され、16進文字列としてシリアライズされます。 |
- シミュレーションで使用するトランザクションは、未署名でなければなりません。
- `Fee``Sequence``SigningPubKey`、または`NetworkID`フィールドが指定されている場合、それらはトランザクションに使用されます。指定されていない場合は、サーバーが自動的に補完します。
## レスポンスのフォーマット
処理が成功したレスポンスの例:
```json
{
"id": 2,
"result": {
"applied": false,
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The simulated transaction would have been applied.",
"ledger_index": 3,
"meta": {
"AffectedNodes": [
{
"ModifiedNode": {
"FinalFields": {
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"AccountTxnID": "4D5D90890F8D49519E4151938601EF3D0B30B16CD6A519D9C99102C9FA77F7E0",
"Balance": "75159663",
"Flags": 9043968,
"OwnerCount": 5,
"Sequence": 361,
"TransferRate": 1004999999
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8",
"PreviousFields": {
"AccountTxnID": "2B44EBE00728D04658E597A85EC4F71D20503B31ABBF556764AD8F7A80BA72F6",
"Balance": "75169663",
"Sequence": 360
},
"PreviousTxnID": "2B44EBE00728D04658E597A85EC4F71D20503B31ABBF556764AD8F7A80BA72F6",
"PreviousTxnLgrSeq": 18555460
}
},
{
"ModifiedNode": {
"FinalFields": {
"Balance": {
"currency": "USD",
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji",
"value": "12.0301"
},
"Flags": 65536,
"HighLimit": {
"currency": "USD",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"value": "0"
},
"HighNode": "0",
"LowLimit": {
"currency": "USD",
"issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"value": "100"
},
"LowNode": "0"
},
"LedgerEntryType": "RippleState",
"LedgerIndex": "96D2F43BA7AE7193EC59E5E7DDB26A9D786AB1F7C580E030E7D2FF5233DA01E9",
"PreviousFields": {
"Balance": {
"currency": "USD",
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji",
"value": "11.0301"
}
},
"PreviousTxnID": "7FFE02667225DFE39594663DEDC823FAF188AC5F036A9C2CA3259FB5379C82B4",
"PreviousTxnLgrSeq": 9787698
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"delivered_amount": {
"currency": "USD",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"value": "1"
}
},
"tx_json": {
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"DeliverMax": {
"currency": "USD",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"value": "1"
},
"Destination": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Fee": "10",
"Sequence": 360,
"TransactionType": "Payment"
}
},
"status": "success",
"type": "response"
}
```
レスポンスは[標準フォーマット][]に従っており、正常に完了した場合は結果に次のフィールドが含まれています。
| フィールド | 型 | 説明 |
| -------------- | ------ | ----------- |
| `tx_json` | オブジェクト | 自動補完された値を含む、シミュレーションされたトランザクション。`binary``false`の場合に含まれます。 |
| `tx_blob` | 文字列 | 自動補完された値を含む、シリアライズされたシミュレーションされたトランザクション。`binary``true`の場合に含まれます。 |
| `ledger_index` | [レジャーインデックス](https://xrpl.org/ja/docs/references/protocol/data-types/basic-data-types#レジャーインデックス) | このトランザクションが含まれていたであろうレジャーインデックス。 |
| `meta` | オブジェクト | トランザクションの結果を示すメタデータ。台帳に含まれないことを意味するコード(たとえば TEC 以外のコード)でトランザクションが失敗した場合は含まれません。`binary``false`の場合に含まれます。 |
| `meta_blob` | 文字列 | トランザクションの結果を示すメタデータ。台帳に含まれないことを意味するコード(たとえば TEC 以外のコード)でトランザクションが失敗した場合は含まれません。`binary``true`の場合に含まれます。 |
## 考えられるエラー
* `invalidParams` - 1つ以上のフィールドの指定が正しくないか、1つ以上の必須フィールドが指定されていません。
* `transactionSigned` - トランザクションが署名済みです。シミュレーションで使用するトランザクションは、未署名でなければなりません。
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -24,7 +24,7 @@ XRP Ledgerには2種類の通貨、XRPと[トークン](../../../concepts/tokens
| 最小値: `0` (負の値はありません) | 最小値: `-9999999999999999e80` ゼロでない絶対値の最小値: `1000000000000000e-96`
| 最大値 `100000000000` (10<sup>11</sup>) XRP (`100000000000000000` (10<sup>17</sup>) "drops") | 最大値 `9999999999999999e80` |
| 最小の精度: "drop" (0.000001 XRP) | 小数点以下15桁の精度 |
| [凍結](../../../concepts/tokens/fungible-tokens/freezes.md)できません | 発行者は残高を[凍結](../../../concepts/tokens/fungible-tokens/freezes.md)することができます |
| [フリーズ](../../../concepts/tokens/fungible-tokens/freezes.md)できません | 発行者は残高を[フリーズ](../../../concepts/tokens/fungible-tokens/freezes.md)することができます |
| 送金手数料はかかりません。XRP同士の支払いは常に直接行われます | 間接的な[パス](../../../concepts/tokens/fungible-tokens/paths.md)を取ることができ、各発行者は一定の[送金手数料](../../../concepts/tokens/transfer-fees.md)を請求できます |
| [ペイメントチャンネル](../../../concepts/payment-types/payment-channels.md)と[エスクロー](../../../concepts/payment-types/escrow.md)で使用できます | ペイメントチャネルやエスクローには対応していません |

View File

@@ -98,8 +98,8 @@ AccountRootオブジェクトは`Flags`フィールドに以下のフラグを
| `lsfDisallowIncomingPayChan` | `0x10000000` | 268435456 | `asfDisallowIncomingPayChan` | このアカウントを宛先とするペイメントチャネルの作成をブロックします。 _([DisallowIncoming Amendment][]により追加されました。)_ |
| `lsfDisallowIncomingTrustline` | `0x20000000` | 536870912 | `asfDisallowIncomingTrustline` | このアカウントに対するトラストラインの作成をブロックします。 _([DisallowIncoming Amendment][]により追加されました。)_ |
| `lsfDisallowXRP` | `0x00080000` | 524288 | `asfDisallowXRP` | クライアントアプリケーションはこのアカウントにXRPを送金しないでください。`rippled`により強制されるものではありません。 |
| `lsfGlobalFreeze` | `0x00400000` | 4194304 | `asfGlobalFreeze` | このアドレスが発行するすべての資産が凍結されます。 |
| `lsfNoFreeze` | `0x00200000` | 2097152 | `asfNoFreeze` | このアドレスは、このアドレスに接続しているトラストラインを凍結できません。一度有効にすると、無効にできません。 |
| `lsfGlobalFreeze` | `0x00400000` | 4194304 | `asfGlobalFreeze` | このアドレスが発行するすべての資産がフリーズされます。 |
| `lsfNoFreeze` | `0x00200000` | 2097152 | `asfNoFreeze` | このアドレスは、このアドレスに接続しているトラストラインをフリーズできません。一度有効にすると、無効にできません。 |
| `lsfPasswordSpent` | `0x00010000` | 65536 | (なし) | このアカウントは無料のSetRegularKeyトランザクションを使用しています。 |
| `lsfRequireAuth` | `0x00040000` | 262144 | `asfRequireAuth` | このアカウントは、他のユーザがこのアカウントのトークンを保有することを個別に承認する必要があります。 |
| `lsfRequireDestTag` | `0x00020000` | 131072 | `asfRequireDest` | 受信ペイメントには宛先タグの指定が必要です。 |

View File

@@ -80,8 +80,8 @@ labels:
| `lsfHighAuth` | `0x00080000` | 524288 | `tfSetAuth` | 高位アカウントにより、低位アカウントが高位アカウントのイシュアンスを保有することが承認されています。 |
| `lsfLowNoRipple` | `0x00100000` | 1048576 | `tfSetNoRipple` | 低位アカウントで、このトラストラインから、同じアカウントのNoRippleフラグが設定されている他のトラストラインへの[Ripplingが無効化されています](../../../../concepts/tokens/fungible-tokens/rippling.md)。 |
| `lsfHighNoRipple` | `0x00200000` | 2097152 | `tfSetNoRipple` | 高位アカウントで、このトラストラインから、同じアカウントのNoRippleフラグが設定されている他のトラストラインへの[Ripplingが無効化されています](../../../../concepts/tokens/fungible-tokens/rippling.md)。 |
| `lsfLowFreeze` | `0x00400000` | 4194304 | `tfSetFreeze` | 低位アカウントがトラストラインを凍結しており、高位アカウントから資産を移動できません。 |
| `lsfHighFreeze` | `0x00800000` | 8388608 | `tfSetFreeze` | 高位アカウントがトラストラインを凍結しており、低位アカウントから資産を移動できません。 |
| `lsfLowFreeze` | `0x00400000` | 4194304 | `tfSetFreeze` | 低位アカウントがトラストラインをフリーズしており、高位アカウントから資産を移動できません。 |
| `lsfHighFreeze` | `0x00800000` | 8388608 | `tfSetFreeze` | 高位アカウントがトラストラインをフリーズしており、低位アカウントから資産を移動できません。 |
トラストラインによって接続された2つのアカウントは、[TrustSetトランザクション][]を使用して、それぞれの設定を変更することができます。

View File

@@ -45,7 +45,7 @@ labels:
| `tecINVARIANT_FAILED` | 147 | このトランザクションを実行しようとしたところ、不変性チェックが失敗しました。[EnforceInvariants Amendment][]により追加されました。このエラーを再現できる場合は、[問題を報告](https://github.com/XRPLF/rippled/issues)してください。 |
| `tecKILLED` | 150 | [OfferCreateトランザクション][]がtfFillOrKillフラグを指定しましたが、トランザクションを確定できなかったため、このトランザクションは取り消されました。_[fix1578 Amendment][]により追加されました。_ |
| `tecMAX_SEQUENCE_REACHED` | 153 | シーケンス番号フィールドはすでに最大値に達しています。これには`MintedNFTokens`フィールドも含まれます。 _([NonFungibleTokensV1_1 amendment][]により追加されました。)_ |
| `tecNEED_MASTER_KEY` | 142 | このトランザクションはマスターキーを必要とする変更([マスターキーの無効化または残高凍結能力の放棄](../types/accountset.md#accountsetのフラグ)など)を試みました。|
| `tecNEED_MASTER_KEY` | 142 | このトランザクションはマスターキーを必要とする変更([マスターキーの無効化または残高フリーズ能力の放棄](../types/accountset.md#accountsetのフラグ)など)を試みました。|
| `tecNFTOKEN_BUY_SELL_MISMATCH` | 155 | [NFTokenAcceptOfferトランザクション][]は、非代替性トークンの購入と売却に関する対応しないオファーをマッチングさせようとしました。 _([NonFungibleTokensV1_1 amendment][]により追加されました。)_ |
| `tecNFTOKEN_OFFER_TYPE_MISMATCH` | 156 | トランザクションで指定されたオファーのうち、1つまたは複数について、オファーの種類が適切ではありませんでした。例えば、`NFTokenSellOffer`フィールドに購入オファーが指定されていました。) _([NonFungibleTokensV1_1 amendment][]により追加されました。)_ |
| `tecNO_ALTERNATIVE_KEY` | 130 | トランザクションが唯一の[トランザクション承認](../../../../concepts/transactions/index.md#トランザクションの承認)メソッドを削除しようとしました。これは、レギュラーキーを削除する[SetRegularKeyトランザクション][]、SignerListを削除する[SignerListSetトランザクション][]、またはマスターキーを無効にする[AccountSetトランザクション][]である可能性があります。(`rippled` 0.30.0より前のバージョンでは、このトランザクションは`tecMASTER_DISABLED`と呼ばれていました。) |

View File

@@ -82,8 +82,8 @@ AccountSetトランザクションは、[XRP Ledgerのアカウント](../../led
| `asfDisallowIncomingPayChan` | 14 | `lsfDisallowIncomingPayChan` | ペイメントチャネルの着信をブロックします。_([DisallowIncoming amendment][] が必要です)_。 |
| `asfDisallowIncomingTrustline` | 15 | `lsfDisallowIncomingTrustline` | トラストラインの着信をブロックします。_([DisallowIncoming amendment][] が必要です)_。 |
| `asfDisallowXRP` | 3 | `lsfDisallowXRP` | XRPがこのアカウントに送信されないようにします勧告的なもので、XRP Ledgerのプロトコルでは強制されません。 |
| `asfGlobalFreeze` | 7 | `lsfGlobalFreeze` | このアカウントによって発行されたすべての資産を[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)します。 |
| `asfNoFreeze` | 6 | `lsfNoFreeze` | [個々のトラストラインの凍結またはGlobal Freezeの無効化](../../../../concepts/tokens/fungible-tokens/freezes.md)の機能を永続的に放棄します。このフラグは、有効にした後は無効にできません。 |
| `asfGlobalFreeze` | 7 | `lsfGlobalFreeze` | このアカウントによって発行されたすべての資産を[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)します。 |
| `asfNoFreeze` | 6 | `lsfNoFreeze` | [個々のトラストラインのフリーズまたはGlobal Freezeの無効化](../../../../concepts/tokens/fungible-tokens/freezes.md)の機能を永続的に放棄します。このフラグは、有効にした後は無効にできません。 |
| `asfRequireAuth` | 2 | `lsfRequireAuth` | このアドレスによって発行された残高をユーザが保持することについて、承認を要求します。アドレスにトラストラインが接続されていない場合のみ有効にできます。 |
| `asfRequireDest` | 1 | `lsfRequireDestTag` | トランザクションをこのアカウントに送信するための宛先タグを要求します。 |

View File

@@ -63,7 +63,7 @@ AMMを表す[AMMエントリ][]と[特殊なAccountRootエントリ](../../ledge
| `terNO_ACCOUNT` | リクエストで参照されたいずれかのアカウントが存在しません。|
| `tecNO_AUTH` | 送信者は資産(`Amount`または`Amount2`)のいずれかを保有する権限がありません。 |
| `tecNO_LINE` | 送信者は資産(`Amount`または`Amount2`のうちいずれか1つに対するトラストラインを保有していません。 |
| `tecFROZEN` | 資産(`Amount`または`Amount2`の少なくとも1つが現在[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
| `tecFROZEN` | 資産(`Amount`または`Amount2`の少なくとも1つが現在[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
| `tecUNFUNDED_AMM` | 送信者は`Amount``Amount2`で指定された金額をAMMに入金するための十分な資金を保有していません。 |
| `tecAMM_EXISTS` | この通貨ペアを扱っているAMMが既に存在しています。 |

View File

@@ -128,7 +128,7 @@ AMMDepositトランザクションは、以下のような[`Flags`フィール
| `tecAMM_EMPTY` | 現在、AMM は資産を保有していないため、通常の入金はできません。代わりに、空のAMMの場合の特殊な入金を行う必要があります。 |
| `tecAMM_NOT_EMPTY` | トランザクションで`tfTwoAssetIfEmpty`が指定されましたが、AMMは空ではありませんでした。 |
| `tecAMM_FAILED` | 預け入れの条件が成立しませんでした。例えば、`EPrice`フィールドに指定された実効価格が低すぎる場合など。 |
| `tecFROZEN` | トランザクションは[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されているトークンを預けようとしました。 |
| `tecFROZEN` | トランザクションは[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているトークンを預けようとしました。 |
| `tecINSUF_RESERVE_LINE` | このトランザクションの送信者は、この処理による[準備金要件](../../../../concepts/accounts/reserves.md)の増加の対象であり、LPトークンを保持するための新しいトラストラインが必要で、そのための追加の所有者準備金分のXRPを保有していないためと思われます。 |
| `tecUNFUNDED_AMM` | 送信者の残高が、指定された預け入れを行うのに十分な量ではありません。 |
| `temBAD_AMOUNT` | トランザクションで指定された金額が無効です。例えば、金額がマイナスなど。 |

View File

@@ -114,7 +114,7 @@ AMMWithdrawトランザクションは、以下のように[`Flags`フィール
| `tecAMM_BALANCE` | トランザクションによって、プールから1つの資産をすべて引き出そうとしている、もしくは`tfWithdrawAll`の場合に端数処理によって0以外の金額が残ってしまっています。 |
| `tecAMM_FAILED` | 例えば、`EPrice`フィールドに指定された有効価格が低過ぎる場合など、出金に関する条件が成立しませんでした。 |
| `tecAMM_INVALID_TOKENS` | トークンペアのAMMが存在しないか、計算の結果、引き出し額がゼロに丸められました。 |
| `tecFROZEN` | トランザクションは[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されたトークンを引き出そうとしました。 |
| `tecFROZEN` | トランザクションは[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されたトークンを引き出そうとしました。 |
| `tecINSUF_RESERVE_LINE` | トランザクションの送信者は、このトランザクションを処理するための[準備金要件](../../../../concepts/accounts/reserves.md)の増加に対応できません。おそらく、引き出される資産の1つを保持するために少なくとも1つの新しいトラストラインが必要ですが、新しいトラストラインのための追加の所有者準備金分のXRPを持っていないためでしょう。 |
| `tecNO_AUTH` | 送信者は、引き出し資産のいずれかを保有する権限を有していません。 |
| `temMALFORMED` | トランザクションで無効なフィールドの組み合わせが指定されました。[AMMWithdrawモード](#ammwithdrawモード)をご覧ください。 |

View File

@@ -45,7 +45,7 @@ _[Checks Amendment][]が必要です_
- `Destination`がトランザクションの送信者である場合、トランザクションは結果コード`temREDUNDANT`で失敗します。
- `Destination`[アカウント](../../../../concepts/accounts/index.md)がレジャーに存在していない場合、トランザクションは結果コード`tecNO_DST`で失敗します。
- `Destination`アカウントでRequireDestフラグが有効であるが、トランザクションに`DestinationTag`フィールドが含まれていない場合、トランザクションは結果コード`tecDST_TAG_NEEDED`で失敗します。
- `SendMax`に[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されているトークンが指定されている場合、トランザクションは結果コード`tecFROZEN`で失敗します。
- `SendMax`に[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているトークンが指定されている場合、トランザクションは結果コード`tecFROZEN`で失敗します。
- トランザクションの`Expiration`が過去の日時である場合、トランザクションは結果コード`tecEXPIRED`で失敗します。
- Checkの追加後に送金元が[所有者準備金](../../../../concepts/accounts/reserves.md#所有者準備金)条件を満たすのに十分なXRPを保有していない場合、トランザクションは結果コード`tecINSUFFICIENT_RESERVE`で失敗します。
- Checkの送金元または送金先のいずれかがレジャーでこれ以上のオブジェクトを所有できない場合、トランザクションは結果コード`tecDIR_FULL`で失敗します。

View File

@@ -98,7 +98,7 @@ _([NonFungibleTokensV1_1 amendment][]により追加されました)_
| `temMALFORMED` | トランザクションのフォーマットが正しくありません。たとえば、`NFTokenSellOffer``NFTokenBuyOffer`のどちらも指定されていないか、`NFTokenBrokerFee`に負の値が指定されています。|
| `tecCANT_ACCEPT_OWN_NFTOKEN_OFFER` | 購入者と販売者が同じアカウントになっています。 |
| `tecEXPIRED` | トランザクションで指定されたオファーの有効期限が既に切れています。 |
| `tecINSUFFICIENT_FUNDS` | 購入者が申し出た金額を全額持っていない。購入額がXRPで指定されている場合、[所有者準備金](../../../../concepts/accounts/reserves.md)が原因である可能性があります。購入額がトークンである場合、トークンが[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md) されていることが原因と考えられます。 |
| `tecINSUFFICIENT_FUNDS` | 購入者が申し出た金額を全額持っていない。購入額がXRPで指定されている場合、[所有者準備金](../../../../concepts/accounts/reserves.md)が原因である可能性があります。購入額がトークンである場合、トークンが[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md) されていることが原因と考えられます。 |
| `tecINSUFFICIENT_PAYMENT` | ブローカーモードにおいて、提示された購入額は、`BrokerFee` _および_ `NFToken`の売却コストを支払うには十分な額ではありません。 |
| `tecOBJECT_NOT_FOUND` | トランザクションで指定されたオファーがレジャーに存在しません。 |
| `tecNFTOKEN_BUY_SELL_MISMATCH` | ブローカーモードにおいて、2つのオファーが有効なマッチングではありません。例えば、販売者が購入者の提示額よりも高い金額を提示している、購入と売却のオファーが異なる通貨で提示されている、販売者が購入者や ブローカーとは異なる販売先を指定している、などです。 |

View File

@@ -59,14 +59,14 @@ NFTokenCreateOfferタイプのトランザクションは、以下のように[`
| `temBAD_EXPIRATION` | 指定された`Expiration`は無効です(例:`0`)。 |
| `tecDIR_FULL` | 送信者がレジャーにすでにあまりにも多くのオブジェクトを所有しているか、またはこのトークンの売買のオファーがあまりにも多く存在しています。 |
| `tecEXPIRED` | 指定された`Expiration`の時間は既に経過しています。 |
| `tecFROZEN` | `Amount`はトークンで、このオファーからトークンを受け取るトラストラインは[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。これは売却者のトラストラインか、`NFToken`の発行者のトラストライン(`NFToken`に送金手数料がある場合)である可能性があります。 |
| `tecFROZEN` | `Amount`はトークンで、このオファーからトークンを受け取るトラストラインは[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。これは売却者のトラストラインか、`NFToken`の発行者のトラストライン(`NFToken`に送金手数料がある場合)である可能性があります。 |
| `tecINSUFFICIENT_RESERVE` | 送信者はこのオファーを提示した後、[所有者準備金](../../../../concepts/accounts/reserves.md)を満たすのに十分なXRPを持っていません。 |
| `tecNO_DST` | `Destination`に指定されたアカウントがレジャーに存在しません。 |
| `tecNO_ENTRY` | `NFToken`フィールドで指定したアカウントは所有していません。 |
| `tecNO_ISSUER` | `Amount`フィールドで指定した発行者が存在しません。 |
| `tecNO_LINE` | `Amount`フィールドはトークンですが、`NFToken`の発行者はそのトークンのトラストラインを持っておらず、`NFToken`は[`lsfTrustLine`フラグ](../../data-types/nftoken.md#nftoken-フラグ)が有効ではありません。 |
| `tecNO_PERMISSION` | `Destination`アカウントが着信する NFTokenOffer をブロックします。 _([DisallowIncoming amendment][] が必要です。)_
| `tecUNFUNDED_OFFER` | 購入オファーの場合、送信者は`Amount`フィールドで指定された通貨を利用可能です。もし`Amount`がXRPである場合、これは準備不足によるものかもしれません。もし`Amount`がトークンである場合、これは[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されている可能性があります。 |
| `tecUNFUNDED_OFFER` | 購入オファーの場合、送信者は`Amount`フィールドで指定された通貨を利用可能です。もし`Amount`がXRPである場合、これは準備不足によるものかもしれません。もし`Amount`がトークンである場合、これは[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されている可能性があります。 |
| `tefNFTOKEN_IS_NOT_TRANSFERABLE` | `NFToken`は[`lsfTransferable`フラグ](../../data-types/nftoken.md#nftoken-flags)が無効になっており、このトランザクションでは`NFToken`を発行者に転送したり発行者から転送したりすることはできません。 |
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,6 +1,4 @@
---
html: nftokenmint.html
parent: transaction-types.html
seo:
description: NFTokenMintを使用して新規NFTを発行する。
labels:
@@ -62,6 +60,7 @@ NFTokenMint型のトランザクションでは、以下のように[`Flags`フ
| `tfOnlyXRP` | `0x00000002` | 2 | 発行された`NFToken`はXRPでのみ売買が可能です。これは、トークンに送金手数料がかかり、発行者がXRP以外のトークンで手数料を受け取りたくない場合に望ましいでしょう。 |
| `tfTrustLine` | `0x00000004` | 4 | **非推奨** 発行者が、発行した`NFToken`を転送する際に受け取る手数料を保有するために、自動的に[トラストライン](../../../../concepts/tokens/fungible-tokens/index.md) を作成します。[fixRemoveNFTokenAutoTrustLine Amendment][]により、このフラグの設定は無効となります。 |
| `tfTransferable` | `0x00000008` | 8 | 発行された`NFToken`は他の人に譲渡することができます。このフラグが _有効でない_ 場合、トークンは _発行者から_ 、または _発行者へ_ のみ転送することができます。 |
| `tfMutable` | `0x00000010` | 16 | 発行された`NFToken``URI`フィールドは、`NFTokenModify`トランザクションを使用して更新することができます。 |
## 追加情報の埋め込み

View File

@@ -0,0 +1,47 @@
---
seo:
description: ダイナミックNFTを変更します。
labels:
- 非代替性トークン, トークン, NFT
title:
- NFTokenModify
---
# NFTokenModify
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/NFTokenModify.cpp "ソース")
`NFTokenModify`は、NFTの`URI`フィールドを別のURIに変更し、NFTのサポートデータを更新するために使用されます。NFTは、`tfMutable`フラグが設定された状態でミントされている必要があります。[ダイナミックNFT](../../../../concepts/tokens/nfts/dynamic-nfts.md)をご覧ください。
## {% $frontmatter.seo.title %} JSONの例
```json
{
"TransactionType": "NFTokenModify",
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"Owner": "rogue5HnPRSszD9CWGSUz8UGHMVwSSKF6",
"Fee": "10",
"Sequence": 33,
"NFTokenID": "0008C350C182B4F213B82CCFA4C6F59AD76F0AFCFBDF04D5A048C0A300000007",
"URI": "697066733A2F2F62616679626569636D6E73347A736F6C686C6976346C746D6E356B697062776373637134616C70736D6C6179696970666B73746B736D3472746B652F5665742E706E67"
}
```
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
| フィールド | JSONの型 | [内部の型][] | 説明 |
|:------------------|:---------|:-------------|:-------------------|
| `TransactionType` | 文字列 | UINT16 | `NFTokenModify` |
| `Account` | 文字列 | AccountID | NFTの発行者または許可されたアカウントの一意のアドレス。 |
| `Owner` | 文字列 | AccountID | _(任意)_ NFTの所有者のアドレス。`Account``Owner`が同じアドレスの場合、このフィールドは省略します。 |
| `NFTokenID` | 文字列 | Hash256 | NFTを識別する一意のID。 |
| `URI` | 文字列 | Blob | _(任意)_ 最大256バイトの任意のデータ。JSONでは、16進数の文字列としてエンコードされます。[`xrpl.convertStringToHex`](https://js.xrpl.org/modules.html#convertStringToHex)ユーティリティメソッドを使用してURIを16進数に変換できます。これは、NFTに関連するデータまたはメタデータを指すURIです。URIはHTTPまたはHTTPS URL、IPFS URI、マグネットリンク、[RFC 2379 "data" URL](https://datatracker.ietf.org/doc/html/rfc2397)としてエンコードされた即値データ、または発行者固有のエンコードをデコードできます。URIは検証されません。URIを指定しない場合、既存のURIは削除されます。 |
## エラーケース
すべてのトランザクションで発生する可能性のあるエラーに加えて、{% $frontmatter.seo.title %}トランザクションでは、次の[トランザクション結果コード](../transaction-results/index.md)が発生する可能性があります。
| エラーコード | 説明 |
|:-------------------|:-----------|
| `tecNO_PERMISSION` | `tfMutable`フラグが有効になっていないため、`URI`フィールドを更新できません。また、`Account`フィールドがNFTの発行者または許可された発行者でない場合、このエラーを受け取ることがあります。 |
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -67,7 +67,7 @@ OfferCreate型のトランザクションについては、[`Flags`フィール
| `temBAD_CURRENCY` | トランザクションで通貨コードが"XRP"のトークンが指定された場合に発生します。 |
| `temBAD_ISSUER` | トランザクションが無効な`issuer`値を持つトークンを指定した場合に発生します。 |
| `tecNO_ISSUER` | トランザクションで、`issuer`の値が台帳の有効化されたアカウントでないトークンを指定した場合に発生します。|
| `tecFROZEN` | [凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)されたトラストライン(ローカルおよびグローバルの凍結を含む)上のトークンを含むトランザクションの場合に発生します。 |
| `tecFROZEN` | [フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されたトラストライン(ローカルおよびグローバルのフリーズを含む)上のトークンを含むトランザクションの場合に発生します。 |
| `tecUNFUNDED_OFFER` | トランザクションの送信者が`TakerGets`の通貨を正の値で保有していない場合に発生する。(例外: `TakerGets`にトランザクションの送信者が発行するトークンを指定した場合、トランザクションは成功します)。 |
| `tecNO_LINE` | 発行者が[Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)を使用しているトークンを含むトランザクションで、必要なトラストラインが存在しない場合に発生します。 |
| `tecNO_AUTH` | 発行者が[Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)を使用しているトークンを含むトランザクションで、トークンを受け取るトラストラインが存在するが認証されていない場合に発生します。 |

View File

@@ -59,7 +59,7 @@ Paymentトランザクションタイプは、いくつかの異なるタイプ
| Paymentの種類 | `Amount` | `SendMax` | `Paths` | `Address` = `Destination`? | 説明 |
| :--------------------------------- | :---------------------------------- | :---------------------------------- | :--------- | :------------------------- | ---- |
| [XRP同士の直接支払い][] | 文字列 (XRP) | 省略 | 省略 | いいえ | アカウント間でへ直接XRPを送金します。常に正確な金額を送信します。基本的な[取引コスト](../../../../concepts/transactions/transaction-cost.md)以外の手数料は適用されません。 |
| [発行通貨の作成・償還][] | オブジェクト | オブジェクト (任意) | 任意 | いいえ | XRP Ledgerに追跡されているXRP以外の通貨や資産の量を増減させます。[送金手数料](../../../../concepts/tokens/transfer-fees.md)と[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)は、直接送金・換金する際には適用されません。 |
| [発行通貨の作成・償還][] | オブジェクト | オブジェクト (任意) | 任意 | いいえ | XRP Ledgerに追跡されているXRP以外の通貨や資産の量を増減させます。[送金手数料](../../../../concepts/tokens/transfer-fees.md)と[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)は、直接送金・換金する際には適用されません。 |
| [クロスカレンシー(通貨間)決済][] | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 通常は必須 | いいえ | 発行された通貨を保有者から別の保有者に送信します。`Amount``SendMax`の両方をXRPにすることはできません。これらの支払いは、発行者を介して[リップリング](../../../../concepts/tokens/fungible-tokens/rippling.md)し、トランザクションがパスセットを指定した場合、複数の仲介者を介してより長い[パス](../../../../concepts/tokens/fungible-tokens/paths.md)を取ることができます。トランザクション形式には、発行者が設定した[送金手数料](../../../../concepts/tokens/transfer-fees.md) が適用されます。これらのトランザクションは、異なる通貨間や、場合によっては同じ通貨コードで異なる発行者の通貨間を接続するために、[分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)のオファーを利用します。 |
| [Partial payment][] | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 通常は必須 | いいえ | 任意の通貨を特定の金額まで送ります。[`tfPartialPayment` フラグ](#paymentのフラグ)を使用します。トランザクションが成功するための最小値を指定する `DeliverMin` 値を含めることができます。トランザクションが `DeliverMin` を指定しない場合、_任意の正の値_ を指定して成功させることができる。 |
| 通貨変換 | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 必須 | はい | [分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)のオファーを消費して、ある通貨を別の通貨に交換し、[裁定取引](https://ja.wikipedia.org/wiki/%E8%A3%81%E5%AE%9A%E5%8F%96%E5%BC%95)の機会を得ることが出来ます。`Amount``SendMax` の両方を XRP にすることはできません。[Data API](../../../data-api.md) は、このタイプの取引を "payment" ではなく、"exchange" として追跡しています。 |

View File

@@ -53,8 +53,8 @@ TrustSetタイプのトランザクションについては、[`Flags`フィー
| `tfSetfAuth` | `0x00010000` | 65536 | [このアカウントから発行された通貨](../../../../concepts/tokens/index.md)を相手方に保有させることを許可します。([*asfRequireAuth* AccountSet フラグ](accountset.md#accountsetのフラグ)を使用しない場合は効果がありません。)設定を解除できません。 |
| `tfSetNoRipple` | `0x00020000` | 131072 | 2つのトラストラインの両方でこのフラグが有効になっている場合、同じ通貨のトラストライン間の[リップリング](../../../../concepts/tokens/fungible-tokens/rippling.md)をブロックする No Ripple フラグを有効にします。 |
| `tfClearNoRipple` | `0x00040000` | 262144 | No Rippleフラグを無効にし、このトラストラインで[リップリング](../../../../concepts/tokens/fungible-tokens/rippling.md)を許可します。 |
| `tfSetFreeze` | `0x00100000` | 1048576 | トラストラインを[凍結](../../../../concepts/tokens/fungible-tokens/freezes.md)します。 |
| `tfClearFreeze` | `0x00200000` | 2097152 | トラストラインを[凍結解除](../../../../concepts/tokens/fungible-tokens/freezes.md)します。 |
| `tfSetFreeze` | `0x00100000` | 1048576 | トラストラインを[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)します。 |
| `tfClearFreeze` | `0x00200000` | 2097152 | トラストラインを[フリーズ解除](../../../../concepts/tokens/fungible-tokens/freezes.md)します。 |
トランザクションがNo Rippleを有効にしようとしたができない場合、結果コード `tecNO_PERMISSION` で失敗します。[fix1578 amendment][]が有効になる前は、このようなトランザクションは代わりに`tesSUCCESS`(可能な限りの他の変更を行う)という結果になりました。

View File

@@ -66,7 +66,7 @@ XRPは、XRP Ledgerの _アカウント_ _ウォレット_ や _アドレス
<!-- STYLE_OVERRIDE: hot wallet, warm wallet, cold wallet, wallet -->
Rippleが推奨するベストプラクティスに従い、Alpha Exchangeは、XRP Ledgerに最低2つのアカウントを作成する必要があります。シークレットキーが悪用された場合の危険を最小限にとどめるため、Rippleでは、[ _コールドアカウント_ 、 _ホットアカウント_ 、 _ウォームアカウント_ ](https://ripple.com/build/issuing-operational-addresses/)(それぞれコールドウォレット、ホットウォレット、ウォームウォレットとも呼ばれる)の作成をお勧めしています。コールド/ホット/ウォームのモデルは、セキュリティと利便性のバランスをとるためのものです。XRPを上場する取引所は、以下のアカウントを作成する必要があります。
Rippleが推奨するベストプラクティスに従い、Alpha Exchangeは、XRP Ledgerに最低2つのアカウントを作成する必要があります。シークレットキーが悪用された場合の危険を最小限にとどめるため、Rippleでは、[ _コールドアカウント_ 、 _ホットアカウント_ 、 _ウォームアカウント_ ](../../concepts/accounts/account-types.md)(それぞれコールドウォレット、ホットウォレット、ウォームウォレットとも呼ばれる)の作成をお勧めしています。コールド/ホット/ウォームのモデルは、セキュリティと利便性のバランスをとるためのものです。XRPを上場する取引所は、以下のアカウントを作成する必要があります。
* 大部分のXRPと顧客の資金を維持する[ _コールドウォレット_ ](../../concepts/accounts/account-types.md#発行アドレス)。取引所にとって、これはユーザが[預入れ](#取引所へのxrpの入金)をするアドレスです。 セキュリティを最適化するため、このアカウントのシークレットキーはオフラインにする必要があります。

View File

@@ -141,16 +141,16 @@ How to transparently report the current number of stablecoins held in reserve.
### トラストラインのFreeze
XRP Ledgerでトークンを発行する場合、_No Freeze_ 設定を有効にすることで、XRP Ledgerのトークン凍結機能を利用することを永久に停止することができます。(注意点として、これは発行されたトークンにのみ適用され、XRPには適用されません)。
XRP Ledgerでトークンを発行する場合、_No Freeze_ 設定を有効にすることで、XRP Ledgerのトークンフリーズ機能を利用することを永久に停止することができます。(注意点として、これは発行されたトークンにのみ適用され、XRPには適用されません)。
_No Freeze_ 設定を有効にしない場合、アカウントが疑わしい動きを示したり、金融機関の利用規約に違反したりした場合、問題を解決する間、トラストラインを凍結する選択肢があります。
_No Freeze_ 設定を有効にしない場合、アカウントが疑わしい動きを示したり、金融機関の利用規約に違反したりした場合、問題を解決する間、トラストラインをフリーズする選択肢があります。
[トラストラインの凍結](../../concepts/tokens/fungible-tokens/freezes.md)をご覧ください。
[トラストラインのフリーズ](../../concepts/tokens/fungible-tokens/freezes.md)をご覧ください。
### Global Freeze
不審な活動の兆候が見られた場合、アカウントをグローバルに凍結し、ユーザがトークンを相互に送信したり、分散型取引所でトークンを取引したりできないようにすることができます。
不審な活動の兆候が見られた場合、アカウントをグローバルにフリーズし、ユーザがトークンを相互に送信したり、分散型取引所でトークンを取引したりできないようにすることができます。
![Global Freeze](/docs/img/uc-stablecoin-global-freeze.png)

View File

@@ -0,0 +1,81 @@
---
category: 2025
date: 2025-mm-dd
seo:
title: SEO最適化済みのタイトル
description: ページ内容を正確に反映した、SEO最適化された説明文155文字以内を推奨
labels:
- 一般
markdown:
editPage:
hide: true
---
# SEO最適化済みのタイトル
ブログ記事の下書きに向けて、最初の一歩を踏み出しましたね! この記事の構成を整理するための出発点として、このテンプレートを活用してください。
<!-- BREAK -->
詳しいガイドラインや例については、[ブログ記事を投稿する](https://xrpl.org/resources/contribute-blog/)をご覧ください。
NOTE: 現在、ブログ記事は英語のみで提供されており、翻訳はまだ行われていません。
## セクション: 便利なリファレンス
すぐに執筆を始められるように、ブログ記事でよく使われる構文のガイドをご用意しました。執筆プロセスを効率化するのに最適です。
**タイトル**
ブログ記事のタイトルや見出しにはタイトルケース(英語の各単語の頭文字を大文字)を使用してください。
SEOに最適化されたタイトルを選びましょう。
タイトルは50文字以内に収め、メタ情報の `seo -> title` フィールドと一致させることを推奨します。
**リンク**
内部リンクを含めるには、相対パスを使用します。 例えば、ドキュメントへの貢献 トピックへのリンクを作成するには以下の構文を使用します。
```
[ドキュメントへの貢献](../resources/contribute-documentation/index.md).
```
外部リンクを含めるには、相対パスではなく絶対URLを使用してください。以下の例をご覧ください。
```
[ドキュメントへの貢献](https://xrpl.org/resources/contribute-documentation).
```
**リスト**
順不同リストを含めるには、以下の構文を使用してください。
- 項目 1
- 項目 2
順序付きリストを含めるには、以下の構文を使用してください。
1. リスト項目 1
2. リスト項目 2
### サブセクション: ブログ記事へ画像を埋め込む方法
画像を含めるには、以下の構文を使用してください。
```
![image_description](/blog/img/my_image.png)
```
画像ファイルは `/blog/img` ディレクトリに保存することを推奨します。
例えば、 `![XRPL Developer Portal](/blog/img/docs-iav3/xrpl-docs-home.png)` と記述すると、以下のように表示されます。
![XRPL Developer Portal](/blog/img/docs-iav3/xrpl-docs-home.png)
### サブセクション: ブログ記事へ動画を埋め込む方法
動画の埋め込み方法については、[ドキュメントへの貢献](https://xrpl.org/resources/contribute-documentation#videos) の該当セクションをご覧ください。

View File

@@ -0,0 +1,42 @@
---
html: contribute-blog.html
parent: resources.html
seo:
description: XRPLブログへの投稿手順
labels:
- ブロックチェーン
---
# ブログ記事を投稿する
XRP Ledger開発者ブログへの投稿をご検討いただきありがとうございます
このページでは、新しいブログ記事を作成するための概要手順を紹介しています。XRP Ledger開発者ポータルへの投稿に関する詳細な手順やガイドラインについては、[ドキュメントへの貢献](../contribute-documentation/index.md)をご覧ください。
{% admonition type="info" name="Note" %}現在、ブログ記事は英語のみで提供されており、まだ翻訳は行われていません。{% /admonition %}
## ブログ投稿用のディレクトリ構成
ソースファイルは、公開されている `xrpl-dev-portal` リポジトリの `blog` ディレクトリにあります。
ブログ記事で使用される画像ファイルは、`blog/img` ディレクトリにあります。
ブログ記事は年ごとに分類されており、2025年に公開されたすべてのブログ記事は `blog/2025` ディレクトリにあります。
## ブログ記事の新規作成手順
新しい記事を作成するには、以下の手順に従ってください。
1. 作業を始める前に、`xrpl-dev-portal` リポジトリの上流upstream`master` ブランチから最新の更新をプルしておいてください。
2. `blog-{記事の概要}` の形式で、新しいブログ記事用のブランチを作成してください。
3. `blog/{年}` フォルダ内に、新しいMarkdownファイルを作成してください。たとえば、以下のようになりますhttps://github.com/XRPLF/xrpl-dev-portal/tree/master/blog/2025
4. 下書きのブログ記事は、テンプレートファイル [`_blog_template.md`](https://github.com/XRPLF/xrpl-dev-portal/tree/master/%40l10n/ja/resources/contribute-blog/_blog-template.md) を参考にして作成してください。
5. 新しく作成したファイルを `blog/sidebars.yaml` に追加してください。
6. 下書きがレビュー可能な状態になったら、内容を保存し、コミットを実行してください。
7. master ブランチへのマージ用に、新しいプルリクエストを作成してください。

View File

@@ -17,13 +17,18 @@ labels:
| 名前 | 登場 | ステータス |
|:----------------------------------|:-----------|:------------------------------------|
| [AMMClawback][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [DynamicNFT][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}投票中: 2025-03-06{% /badge %} |
| [DeepFreeze][] | v2.4.0 | {% badge href="https://livenet.xrpl.org/transactions/976281D793337FF5377A36409F2A1432DADAB64DB5064E12E71B1AC491EA3021" %}有効: 2025-05-04{% /badge %} |
| [PermissionedDomains][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}投票中: 2025-03-06{% /badge %} |
| [fixFrozenLPTokenTransfer][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}投票中: 2025-03-06{% /badge %} |
| [fixInvalidTxFlags][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}投票中: 2025-03-06{% /badge %} |
| [AMMClawback][] | v2.3.0 | {% badge href="https://livenet.xrpl.org/transactions/8672DFD11FCF79F8E8F92E300187E8E533899ED8C8CF5AFB1A9C518195C16261" %}有効: 2025-01-30{% /badge %} |
| [Credentials][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [fixAMMv1_2][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [fixEnforceNFTokenTrustline][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [fixInnerObjTemplate2][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [fixNFTokenPageLinks][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [fixReducedOffersV2][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [fixAMMv1_2][] | v2.3.0 | {% badge href="https://livenet.xrpl.org/transactions/71D5031A5BD927BDFE424E51699E69F2784097D615D0852BF20C168BA9B5EA76" %}有効: 2025-01-30{% /badge %} |
| [fixEnforceNFTokenTrustline][] | v2.3.0 | {% badge href="https://livenet.xrpl.org/transactions/606FA84C4BA30F67582C11A39BBFC11A9D994E114CD515E9F63FC7D8701A8ED9" %}有効: 2025-01-30{% /badge %} |
| [fixInnerObjTemplate2][] | v2.3.0 | {% badge href="https://livenet.xrpl.org/transactions/426314C8BC64BA339E97E53B278602ADC44F115056274BF7971F694C9A8AF946" %}有効: 2025-01-30{% /badge %} |
| [fixNFTokenPageLinks][] | v2.3.0 | {% badge href="https://livenet.xrpl.org/transactions/2D9A29768A7FA4BAC01DF1941380077E304785279E5E49267EC269F53ABADF5A" %}有効: 2025-01-30{% /badge %} |
| [fixReducedOffersV2][] | v2.3.0 | {% badge href="https://livenet.xrpl.org/transactions/6D325D5EFF8230F1FECA3EE6418C9678637F3F56B0CA247013F70B3BDCFE75C8" %}有効: 2025-01-30{% /badge %} |
| [MPTokensV1][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [NFTokenMintOffer][] | v2.3.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.3.0" %}投票中: 2024-11-26{% /badge %} |
| [fixXChainRewardRounding][] | v2.2.0 | {% badge href="https://xrpl.org/blog/2024/rippled-2.2.0" %}投票中: 2024-06-04{% /badge %} |
@@ -170,7 +175,7 @@ labels:
| Amendment | AMMClawback |
| :----------------------------- | :--------------------------------------------------------------- |
| Amendment ID | 726F944886BCDF7433203787E93DD9AA87FAB74DFE3AF4785BA03BEFC97ADA1F |
| ステータス | 投票中 |
| ステータス | 有効 |
| デフォルトの投票(最新の安定版) | いいえ |
| Amendment前の機能は廃止? | いいえ |
@@ -178,7 +183,7 @@ labels:
- **AMMClawback** - トークンにClawbackが有効になっている場合、発行者は、AMMに預けられたトークンをClawbackできるようになります。
AMMDepositトランザクションタイプを修正し、AMMに凍結されたトークンを預けることを防ぎます。
AMMDepositトランザクションタイプを修正し、AMMにフリーズされたトークンを預けることを防ぎます。
詳細については、[XLS-73: AMMClawback specification](https://github.com/XRPLF/XRPL-Standards/discussions/212)をご覧ください。

View File

@@ -478,8 +478,8 @@ Trust Lines: トラストライン
No spamming of wallets without permission.: 許可なくウォレットにスパムを送信することはありません。
Authorized Trustlines: 認可トラストライン
Control who can hold your tokens with allowlisting.: ホワイトリスト形式で誰がトークンを保持できるかを制御します。
Freeze & Clawbacks: 凍結とクローバック
Freeze: 凍結
Freeze & Clawbacks: フリーズとクローバック
Freeze: フリーズ
If you see signs of suspicious activity, you can suspend trading of your token while investigating the issue.: 不審な活動の兆候が見られた場合は、問題を調査する間、トークンの取引を停止することができます。
Clawback: クローバック
"Recover tokens distributed to accounts in error: for example, reclaim funds sent to an account sanctioned for illegal activity.": 誤ってアカウントに送信されたトークンを回収することができます。たとえば、違法行為に対して制裁を受けたアカウントに送金された資金を回収します。

View File

@@ -6,32 +6,64 @@ import { Link } from "@redocly/theme/components/Link/Link";
import { ColorModeSwitcher } from "@redocly/theme/components/ColorModeSwitcher/ColorModeSwitcher";
import { Search } from "@redocly/theme/components/Search/Search";
import arrowUpRight from "../../../static/img/icons/arrow-up-right-custom.svg";
import moment from "moment-timezone";
// @ts-ignore
const alertBanner = {
show: true,
show: false,
message: "APEX 2025",
button: "REGISTER",
link: "https://www.xrpledgerapex.com/?utm_source=xrplwebsite&utm_medium=direct&utm_campaign=xrpl-event-ho-xrplapex-glb-2025-q1_xrplwebsite_ari_arp_bf_rsvp&utm_content=cta_btn_english_pencilbanner",
date: "AGENDA NOW LIVE",
link: "https://www.xrpledgerapex.com/?utm_source=xrplwebsite&utm_medium=direct&utm_campaign=xrpl-event-ho-xrplapex-glb-2025-q1_xrplwebsite_ari_arp_bf_rsvp&utm_content=cta_btn_english_pencilbanner"
};
export function AlertBanner({ message, date, button, link, show }) {
export function AlertBanner({ message, button, link, show }) {
const { useTranslate } = useThemeHooks();
const { translate } = useTranslate();
const bannerRef = React.useRef(null);
const [displayDate, setDisplayDate] = React.useState("JUNE 10-12");
React.useEffect(() => {
const calculateCountdown = () => {
// Calculate days until June 11, 2025 8AM Singapore time
// This will automatically adjust for the user's timezone
const target = moment.tz('2025-06-11 08:00:00', 'Asia/Singapore');
const now = moment();
const daysUntil = target.diff(now, 'days');
// Show countdown if event is in the future, otherwise show the provided date
let newDisplayDate = "JUNE 10-12";
if (daysUntil > 0) {
newDisplayDate = daysUntil === 1 ? 'IN 1 DAY' : `IN ${daysUntil} DAYS`;
} else if (daysUntil === 0) {
// Check if it's today
const hoursUntil = target.diff(now, 'hours');
newDisplayDate = hoursUntil > 0 ? 'TODAY' : "JUNE 10-12";
}
setDisplayDate(newDisplayDate);
};
// Calculate immediately
calculateCountdown();
// Update every hour
const interval = setInterval(calculateCountdown, 60 * 60 * 1000);
return () => clearInterval(interval);
}, []);
React.useEffect(() => {
const banner = bannerRef.current;
if (!banner) return;
const handleMouseEnter = () => {
banner.classList.add('has-hover');
banner.classList.add("has-hover");
};
// Attach the event listener
banner.addEventListener('mouseenter', handleMouseEnter);
banner.addEventListener("mouseenter", handleMouseEnter);
// Clean up the event listener on unmount
return () => {
banner.removeEventListener('mouseenter', handleMouseEnter);
banner.removeEventListener("mouseenter", handleMouseEnter);
};
}, []);
@@ -47,11 +79,15 @@ export function AlertBanner({ message, date, button, link, show }) {
>
<div className="banner-event-details">
<div className="event-info">{translate(message)}</div>
<div className="event-date">{translate(date)}</div>
<div className="event-date">{displayDate}</div>
</div>
<div className="banner-button">
<div className="button-text">{translate(button)}</div>
<img className="button-icon" src={arrowUpRight} alt="Get Tickets Icon" />
<img
className="button-icon"
src={arrowUpRight}
alt="Get Tickets Icon"
/>
</div>
</a>
);
@@ -91,7 +127,6 @@ export function Navbar(props) {
}
});
React.useEffect(() => {
// Turns out jQuery is necessary for firing events on Bootstrap v4
// dropdowns. These events set classes so that the search bar and other
@@ -139,7 +174,7 @@ export function Navbar(props) {
<NavItems>
{navItems}
<div id="topnav-search" className="nav-item search">
<Search className="topnav-search"/>
<Search className="topnav-search" />
</div>
<div id="topnav-language" className="nav-item">
<LanguagePicker

View File

@@ -10,7 +10,7 @@
"https-browserify": "^1.0.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"vite": "^4.5.13"
"vite": "^4.5.14"
},
"dependencies": {
"dotenv": "^16.0.3",

View File

@@ -172,6 +172,13 @@ asn1.js@^4.10.1:
inherits "^2.0.1"
minimalistic-assert "^1.0.0"
available-typed-arrays@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==
dependencies:
possible-typed-array-names "^1.0.0"
bignumber.js@^9.0.0:
version "9.1.2"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
@@ -258,6 +265,32 @@ builtin-status-codes@^3.0.0:
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==
call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
call-bind@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c"
integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
dependencies:
call-bind-apply-helpers "^1.0.0"
es-define-property "^1.0.0"
get-intrinsic "^1.2.4"
set-function-length "^1.2.2"
call-bound@^1.0.3, call-bound@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a"
integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==
dependencies:
call-bind-apply-helpers "^1.0.2"
get-intrinsic "^1.3.0"
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.6.tgz#8fe672437d01cd6c4561af5334e0cc50ff1955f7"
@@ -279,7 +312,7 @@ create-ecdh@^4.0.4:
bn.js "^4.1.0"
elliptic "^6.5.3"
create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
create-hash@^1.1.0, create-hash@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
@@ -290,7 +323,17 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
ripemd160 "^2.0.1"
sha.js "^2.4.0"
create-hmac@^1.1.4, create-hmac@^1.1.7:
create-hash@~1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
integrity sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==
dependencies:
cipher-base "^1.0.1"
inherits "^2.0.1"
ripemd160 "^2.0.0"
sha.js "^2.4.0"
create-hmac@^1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
@@ -320,6 +363,15 @@ crypto-browserify@^3.12.0:
randombytes "^2.1.0"
randomfill "^1.0.4"
define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
gopd "^1.0.1"
des.js@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da"
@@ -342,6 +394,15 @@ dotenv@^16.0.3:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-errors "^1.3.0"
gopd "^1.2.0"
elliptic@^6.5.3, elliptic@^6.5.5:
version "6.6.1"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06"
@@ -355,6 +416,23 @@ elliptic@^6.5.3, elliptic@^6.5.5:
minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
es-define-property@^1.0.0, es-define-property@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
dependencies:
es-errors "^1.3.0"
esbuild@^0.18.10:
version "0.18.20"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
@@ -401,11 +479,78 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
for-each@^0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47"
integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==
dependencies:
is-callable "^1.2.7"
fsevents@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
get-intrinsic@^1.2.4, get-intrinsic@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
dependencies:
call-bind-apply-helpers "^1.0.2"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.1.1"
function-bind "^1.1.2"
get-proto "^1.0.1"
gopd "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
math-intrinsics "^1.1.0"
get-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
dependencies:
dunder-proto "^1.0.1"
es-object-atoms "^1.0.0"
gopd@^1.0.1, gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
has-property-descriptors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
es-define-property "^1.0.0"
has-symbols@^1.0.3, has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
has-tostringtag@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
dependencies:
has-symbols "^1.0.3"
hash-base@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
integrity sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==
dependencies:
inherits "^2.0.1"
hash-base@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
@@ -431,6 +576,13 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"
hasown@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -450,11 +602,33 @@ inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
is-callable@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-typed-array@^1.1.14:
version "1.1.15"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b"
integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
dependencies:
which-typed-array "^1.1.16"
isarray@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
math-intrinsics@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@@ -500,21 +674,27 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.7:
safe-buffer "^5.2.1"
pbkdf2@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075"
integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==
version "3.1.3"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.3.tgz#8be674d591d65658113424592a95d1517318dd4b"
integrity sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==
dependencies:
create-hash "^1.1.2"
create-hmac "^1.1.4"
ripemd160 "^2.0.1"
safe-buffer "^5.0.1"
sha.js "^2.4.8"
create-hash "~1.1.3"
create-hmac "^1.1.7"
ripemd160 "=2.0.1"
safe-buffer "^5.2.1"
sha.js "^2.4.11"
to-buffer "^1.2.0"
picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
possible-typed-array-names@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae"
integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
postcss@^8.4.27:
version "8.5.1"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214"
@@ -578,6 +758,14 @@ readable-stream@^3.5.0, readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
ripemd160@=2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
integrity sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==
dependencies:
hash-base "^2.0.0"
inherits "^2.0.1"
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
@@ -629,7 +817,19 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
sha.js@^2.4.0, sha.js@^2.4.8:
set-function-length@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
gopd "^1.0.1"
has-property-descriptors "^1.0.2"
sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8:
version "2.4.11"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
@@ -674,15 +874,33 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
to-buffer@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.1.tgz#2ce650cdb262e9112a18e65dc29dcb513c8155e0"
integrity sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==
dependencies:
isarray "^2.0.5"
safe-buffer "^5.2.1"
typed-array-buffer "^1.0.3"
typed-array-buffer@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536"
integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==
dependencies:
call-bound "^1.0.3"
es-errors "^1.3.0"
is-typed-array "^1.1.14"
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
vite@^4.5.13:
version "4.5.13"
resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.13.tgz#778534a947112c6c455e89737730fae5d458a294"
integrity sha512-Hgp8IF/yZDzKsN1hQWOuQZbrKiaFsbQud+07jJ8h9m9PaHWkpvZ5u55Xw5yYjWRXwRQ4jwFlJvY7T7FUJG9MCA==
vite@^4.5.14:
version "4.5.14"
resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.14.tgz#2e652bc1d898265d987d6543ce866ecd65fa4086"
integrity sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==
dependencies:
esbuild "^0.18.10"
postcss "^8.4.27"
@@ -690,6 +908,19 @@ vite@^4.5.13:
optionalDependencies:
fsevents "~2.3.2"
which-typed-array@^1.1.16:
version "1.1.19"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
dependencies:
available-typed-arrays "^1.0.7"
call-bind "^1.0.8"
call-bound "^1.0.4"
for-each "^0.3.5"
get-proto "^1.0.1"
gopd "^1.2.0"
has-tostringtag "^1.0.2"
ws@^8.13.0:
version "8.18.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"

View File

@@ -1,4 +1,4 @@
xrpl-py>=3.0.0
wxPython==4.2.1
toml==0.10.2
requests==2.32.0
requests==2.32.4

View File

@@ -12,13 +12,11 @@ import {
const client = new Client('wss://s.altnet.rippletest.net:51233')
void claimPayChannel()
// The snippet walks us through creating and claiming a Payment Channel.
async function claimPayChannel(): Promise<void> {
await client.connect()
// creating wallets as prerequisite
// Creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
@@ -26,16 +24,17 @@ async function claimPayChannel(): Promise<void> {
console.log(`Balance of ${wallet1.address} is ${await client.getXrpBalance(wallet1.address)} XRP`)
console.log(`Balance of ${wallet2.address} is ${await client.getXrpBalance(wallet2.address)} XRP`)
// create a Payment Channel and submit and wait for tx to be validated
// Create a Payment Channel transaction
const paymentChannelCreate: PaymentChannelCreate = {
TransactionType: 'PaymentChannelCreate',
Account: wallet1.classicAddress,
Amount: '100',
Amount: '3000000', // 3 XRP in drops
Destination: wallet2.classicAddress,
SettleDelay: 86400,
SettleDelay: 86400, // 1 day in seconds
PublicKey: wallet1.publicKey,
}
// Submit and wait for the transaction to be validated
console.log("Submitting a PaymentChannelCreate transaction...")
const paymentChannelResponse = await client.submitAndWait(
paymentChannelCreate,
@@ -44,7 +43,7 @@ async function claimPayChannel(): Promise<void> {
console.log("PaymentChannelCreate transaction response:")
console.log(paymentChannelResponse)
// check that the object was actually created
// Check that the object was actually created
const accountObjectsRequest: AccountObjectsRequest = {
command: 'account_objects',
account: wallet1.classicAddress,
@@ -55,14 +54,14 @@ async function claimPayChannel(): Promise<void> {
console.log("Account Objects:", accountObjects)
// destination claims the Payment Channel and we see the balances to verify.
// Destination claims the Payment Channel and we see the balances to verify.
const paymentChannelClaim: PaymentChannelClaim = {
Account: wallet2.classicAddress,
TransactionType: 'PaymentChannelClaim',
Channel: hashes.hashPaymentChannel(
wallet1.classicAddress,
wallet2.classicAddress,
paymentChannelResponse.result.Sequence ?? 0,
paymentChannelResponse.result.tx_json.Sequence ?? 0,
),
Amount: '100',
}
@@ -70,7 +69,7 @@ async function claimPayChannel(): Promise<void> {
console.log("Submitting a PaymentChannelClaim transaction...")
const channelClaimResponse = await client.submit(paymentChannelClaim, {
wallet: wallet1,
wallet: wallet2,
})
console.log("PaymentChannelClaim transaction response:")
console.log(channelClaimResponse)
@@ -81,3 +80,5 @@ async function claimPayChannel(): Promise<void> {
await client.disconnect()
}
void claimPayChannel()

View File

@@ -0,0 +1,97 @@
"""
Create, claim and verify a Payment Channel.
Reference: https://xrpl.org/paychannel.html
"""
from xrpl.clients import JsonRpcClient
from xrpl.models import (
AccountObjects,
PaymentChannelCreate,
PaymentChannelClaim,
)
from xrpl.wallet import generate_faucet_wallet
from xrpl.transaction import submit_and_wait, submit
from xrpl.account import get_balance
def claim_pay_channel():
"""The snippet walks us through creating and claiming a Payment Channel."""
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
try:
# Creating wallets as prerequisite
print("Creating and funding wallets...")
wallet1 = generate_faucet_wallet(client, debug=True)
wallet2 = generate_faucet_wallet(client, debug=True)
print("Balances of wallets before Payment Channel is claimed:")
balance1 = get_balance(wallet1.address, client)
balance2 = get_balance(wallet2.address, client)
print(f"Balance of {wallet1.address} is {balance1} XRP")
print(f"Balance of {wallet2.address} is {balance2} XRP")
# Create a Payment Channel transaction
payment_channel_create = PaymentChannelCreate(
account=wallet1.address,
amount="3000000", # 3 XRP in drops
destination=wallet2.address,
settle_delay=86400,
public_key=wallet1.public_key,
)
# Submit and wait for the transaction to be validated
print("Submitting a PaymentChannelCreate transaction...")
payment_channel_response = submit_and_wait(
payment_channel_create,
client,
wallet1
)
print("PaymentChannelCreate transaction response:")
print(payment_channel_response)
# Check that the object was actually created and get the channel ID
account_objects_request = AccountObjects(
account=wallet1.address,
)
account_objects_response = client.request(account_objects_request)
account_objects = account_objects_response.result["account_objects"]
# Find the payment channel from account objects and get its ID
channel_id = None
for obj in account_objects:
if obj.get("LedgerEntryType") == "PayChannel":
channel_id = obj["index"]
break
if not channel_id:
raise Exception("Could not find PayChannel in account objects")
print(f"Payment Channel ID: {channel_id}")
# Destination claims the Payment Channel
payment_channel_claim = PaymentChannelClaim(
account=wallet2.address,
channel=channel_id,
amount="100",
sequence=payment_channel_response.result["tx_json"]["Sequence"],
fee="12", # Fee in drops (0.000012 XRP)
)
print("Submitting a PaymentChannelClaim transaction...")
channel_claim_response = submit(
payment_channel_claim,
wallet2,
)
print("PaymentChannelClaim transaction response:")
print(channel_claim_response)
print("Balances of wallets after Payment Channel is claimed:")
print(f"Balance of {wallet1.address} is {get_balance(wallet1.address, client)} XRP")
print(f"Balance of {wallet2.address} is {get_balance(wallet2.address, client)} XRP")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__":
claim_pay_channel()

View File

@@ -0,0 +1 @@
xrpl-py>=2.0.0

View File

@@ -0,0 +1,223 @@
// ******************************************************
// ************* Get the Preferred Network **************
// ******************************************************
function getNet() {
let net
if (document.getElementById("tn").checked) net = "wss://s.altnet.rippletest.net:51233/"
if (document.getElementById("dn").checked) net = "wss://s.devnet.rippletest.net:51233/"
return net
} // End of getNet()
// *******************************************************
// ************* Get Account *****************************
// *******************************************************
async function getAccount() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
resultField.value = `===Getting Account===\n\nConnected to ${net}.`
try {
let faucetHost = null
const my_wallet = (await client.fundWallet(null, { faucetHost})).wallet
const newAccount = [my_wallet.address, my_wallet.seed]
return (newAccount)
}
catch (error) {
console.error('===Error getting account:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
if (client && client.isConnected()) {
await client.disconnect();
} }
} // End of getAccount()
async function getNewAccount1() {
account1address.value = "=== Getting new account. ===\n\n"
account1seed.value = ""
const accountInfo= await getAccount()
account1address.value = accountInfo[0]
account1seed.value = accountInfo[1]
}
async function getNewAccount2() {
account2address.value = "=== Getting new account. ===\n\n"
account2seed.value = ""
const accountInfo= await getAccount()
account2address.value = accountInfo[0]
account2seed.value = accountInfo[1]
}
// *****************************************************
// ********** Get Account from Seed ********************
// *****************************************************
async function getAccountFromSeed(my_seed) {
const net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = '===Finding wallet.===\n\n'
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(my_seed)
const address = wallet.address
results += "===Wallet found.===\n\n"
results += "Account address: " + address + "\n\n"
resultField.value = results
return (address)
}
catch (error) {
console.error('===Error getting account from seed:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
if (client && client.isConnected()) {
await client.disconnect();
} }
} // End of getAccountFromSeed()
// *****************************************************
// ********** Get Account from Seed1 *******************
// *****************************************************
async function getAccountFromSeed1() {
account1address.value = await getAccountFromSeed(account1seed.value)
}
// *****************************************************
// ********** Get Account from Seed2 *******************
// *****************************************************
async function getAccountFromSeed2() {
account2address.value = await getAccountFromSeed(account2seed.value)
}
// *****************************************************
// ************ Gather Account Info ********************
// *****************************************************
function gatherAccountInfo() {
let accountData = account1name.value + "\n" + account1address.value + "\n" + account1seed.value + "\n"
accountData += account2name.value + "\n" + account2address.value + "\n" + account2seed.value
resultField.value = accountData
}
// *****************************************************
// ********** Distribute Account Info ******************
// *****************************************************
function distributeAccountInfo() {
let accountInfo = resultField.value.split("\n")
account1name.value = accountInfo[0]
account1address.value = accountInfo[1]
account1seed.value = accountInfo[2]
account2name.value = accountInfo[3]
account2address.value = accountInfo[4]
account2seed.value = accountInfo[5]
}
// *****************************************************
// ************ Populate Active Form 1 *****************
// *****************************************************
function populate1() {
accountNameField.value = account1name.value
accountAddressField.value = account1address.value
accountSeedField.value = account1seed.value
getXrpBalance()
}
// *****************************************************
// ************ Populate Active Form 2 *****************
// *****************************************************
function populate2() {
accountNameField.value = account2name.value
accountAddressField.value = account2address.value
accountSeedField.value = account2seed.value
getXrpBalance()
}
// *******************************************************
// **************** Get XRP Balance *********************
// *******************************************************
async function getXrpBalance() {
const net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `\n===Getting XRP balance...===\n\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const balance = await client.getXrpBalance(wallet.address)
results += accountNameField.value + " current XRP balance: " + balance + "\n\n"
xrpBalanceField.value = await client.getXrpBalance(accountAddressField.value)
resultField.value = results
}
catch (error) {
console.error('Error getting XRP balance:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
if (client && client.isConnected()) {
await client.disconnect();
} }
} // End of getXrpBalance()
// *******************************************************
// ************** Get Token Balance *********************
// *******************************************************
async function getTokenBalance() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}.===\n===Getting account token balance...===\n\n`
resultField.value += results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const balance = await client.request({
command: "gateway_balances",
account: wallet.address,
ledger_index: "validated",
})
results = accountNameField.value + "\'s token balance(s): " + JSON.stringify(balance.result, null, 2) + "\n"
resultField.value += results
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
}
catch (error) {
console.error('Error getting token balance:', error);
results = `\nError: ${error.message}\n`
resultField.value += results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
if (client && client.isConnected()) {
await client.disconnect();
} }
} // End of getTokenBalance()
// *******************************************************
// **************** Scroll Results ***********************
// *******************************************************
let results
async function updateResults() {
resultField.value += results;
resultField.scrollTop = resultField.scrollHeight;
}
// End of updateResults()

View File

@@ -0,0 +1,201 @@
<html>
<head>
<title>XRPL Base Module</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='send-xrp.js'></script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>XRPL Base Module</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
<td>
<button type="button" onClick="sendXRP()">Send XRP</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getXrpBalance()">Get XRP Balance</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where XRP is sent.">
<lable for="destinationField">Destination</lable>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getTokenBalance()">Get Token Balance</button>
</td>
</tr>
<tr>
<td colspan="2">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,280 @@
<html>
<head>
<title>Create a Conditional Escrow</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src="create-time-escrow.js"></script>
<script src='create-conditional-escrow.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Create a Conditional Escrow</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where the escrow is sent.">
<lable for="destinationField">Destination</lable>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="createConditionalEscrow()">Create Escrow</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Condition code used to begin the escrow transaction.">
<lable for="escrowConditionField">Escrow Condition</lable>
</span>
</td>
<td>
<input type="text" id="escrowConditionField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getEscrows()">Get Escrows</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Fullfillment code to complete the escrow transaction.">
<lable for="escrowFulfillmentField">Escrow Fulfillment</lable>
</span>
</td>
<td>
<input type="text" id="escrowFulfillmentField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="finishConditionalEscrow()">Finish Escrow</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Escrow cancel time, in seconds.">
<lable for="escrowCancelDateField">Escrow Cancel Time</lable>
</span>
</td>
<td>
<input type="text" id="escrowCancelDateField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="cancelEscrow()">Cancel Escrow</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Escrow sequence number, used when finishing the escrow.">
<lable for="escrowSequenceNumberField">Escrow Sequence Number</lable>
</span>
</td>
<td>
<input type="text" id="escrowSequenceNumberField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="getTransaction()">Get Transaction</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Escrow owner, the account that created the escrow.">
<lable for="escrowOwnerField">Escrow Owner</lable>
</span>
</td>
<td>
<input type="text" id="escrowOwnerField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Transaction number, used with the Get Transaction button.">
<lable for="transactionField">Transaction</lable>
</span>
</td>
<td>
<input type="text" id="transactionField" size="40"></input>
<br>
</td>
<td>
</td>
</tr>
<tr>
<td colspan="2">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,86 @@
// *******************************************************
// ************* Create Conditional Escrow ***************
// *******************************************************
async function createConditionalEscrow() {
//------------------------------------------------------Connect to the Ledger
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const sendAmount = amountField.value
let results = `===Connected to ${net}===\n===Creating conditional escrow.===\n\n`
resultField.value = results
let escrow_cancel_date = new Date()
escrow_cancel_date = addSeconds(parseInt(escrowCancelDateField.value))
// ------------------------------------------------------- Prepare transaction
try {
const escrowTx = await client.autofill({
"TransactionType": "EscrowCreate",
"Account": wallet.address,
"Amount": xrpl.xrpToDrops(sendAmount),
"Destination": destinationField.value,
"CancelAfter": escrow_cancel_date,
"Condition": escrowConditionField.value
})
// ------------------------------------------------ Sign prepared instructions
const signed = wallet.sign(escrowTx)
// -------------------------------------------------------- Submit signed blob
const tx = await client.submitAndWait(signed.tx_blob)
results = "\n=== *** Sequence Number (Save!): " + tx.result.tx_json.Sequence
results += "\n\n===Balance changes===\n" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
resultField.value += results
}
catch (error) {
results += "\n===Error: " + error.message
resultField.value = results
}
finally {
// -------------------------------------------------------- Disconnect
client.disconnect()
}
} // End of createTimeEscrow()
// *******************************************************
// ************** Finish Conditional Escrow **************
// *******************************************************
async function finishConditionalEscrow() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}===\n===Fulfilling conditional escrow.===\n`
resultField.value = results
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
try {
// ------------------------------------------------------- Prepare transaction
const prepared = await client.autofill({
"TransactionType": "EscrowFinish",
"Account": accountAddressField.value,
"Owner": escrowOwnerField.value,
"OfferSequence": parseInt(escrowSequenceNumberField.value),
"Condition": escrowConditionField.value,
"Fulfillment": escrowFulfillmentField.value
})
const signed = wallet.sign(prepared)
const tx = await client.submitAndWait(signed.tx_blob)
results += "\n===Balance changes===" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
resultField.value = results
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
}
catch (error) {
results += "\n===Error: " + error.message + ".===\n"
resultField.value = results
}
finally {
// -------------------------------------------------------- Disconnect
client.disconnect()
}
} // End of finisConditionalEscrow()

View File

@@ -0,0 +1,249 @@
<html>
<head>
<title>Create Offers</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='send-xrp.js'></script>
<script src='create-offer.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Create Offers</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
</table>
<table>
<tr>
<td></td>
<td>
<h4 align="center">Taker Pays</h4>
</td>
<td>
<h4 align="center">Taker Gets</h4>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Currency codes for the Pay and Get offers.">
<lable for="payCurrencyField">Currency Code</lable>
</span>
</td>
<td>
<input type="text" id="payCurrencyField" size="40"></input>
</td>
<td>
<input type="text" id="getCurrencyField" size="40"></input>
</td>
<td>
<button type="button" onClick="createOffer()">Create Offer</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuers of the offered currencies.">
<lable for="payIssuerField">Issuer</lable>
</span>
</td>
<td>
<input type="text" id="payIssuerField" size="40"></input>&nbsp;&nbsp;
</td>
<td>
<input type="text" id="getIssuerField" size="40"></input>&nbsp;&nbsp;
</td>
<td>
<button type="button" onClick="getOffers()">Get Offers</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amounts of offered currencies.">
<lable for="amountField">Amount</lable>
</span>
</td>
<td>
<input type="text" id="payAmountField" size="40"></input>
</td>
<td>
<input type="text" id="getAmountField" size="40"></input>
</td>
<td>
<button type="button" onClick="cancelOffer()">Cancel Offer</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Sequence number of the offer.">
<lable for="offerSequenceField">Offer Sequence</lable>
</span>
</td>
<td>
<input type="text" id="offerSequenceField" size="40"></input>
</td>
<td></td>
<td>
<button type="button" onClick="getTokenBalance()">Get Token Balance</button>
</td>
</tr>
<tr>
<td colspan="3">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,121 @@
/***********************************
*********** Create Offer **********
**********************************/
async function createOffer() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}, getting wallet....===\n`
resultField.value = results
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
try {
if (getCurrencyField.value == 'XRP') {
takerGets = xrpl.xrpToDrops(getAmountField.value)
}
else {
takerGetsString = '{"currency": "' + getCurrencyField.value + '",\n' +
'"issuer": "' + getIssuerField.value + '",\n' +
'"value": "' + getAmountField.value + '"}'
takerGets = JSON.parse(takerGetsString)
}
if (payCurrencyField.value == 'XRP') {
takerPays = xrpl.xrpToDrops(payAmountField.value)
} else {
takerPaysString = '{"currency": "' + payCurrencyField.value + '",\n' +
'"issuer": "' + payIssuerField.value + '",\n' +
'"value": "' + payAmountField.value + '"}'
takerPays = JSON.parse(takerPaysString)
}
const prepared = await client.autofill({
"TransactionType": "OfferCreate",
"Account": wallet.address,
"TakerGets": takerGets,
"TakerPays": takerPays
})
const signed = wallet.sign(prepared)
const tx = await client.submitAndWait(signed.tx_blob)
results = '\n\n===Offer created===\n\n' +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
resultField.value += results
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
} catch (err) {
console.error('Error creating offer:', err);
results = `\nError: ${err.message}\n`
resultField.value += results
throw err; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
client.disconnect()
}
} // End of createOffer()
/***********************************
************ Get Offers ***********
**********************************/
async function getOffers() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ' + ${net}, getting offers....===\n`
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
resultField.value = results
results += '\n\n=== Offers ===\n'
let offers
try {
offers = await client.request({
method: "account_offers",
account: wallet.address,
ledger_index: "validated"
})
results = JSON.stringify(offers, null, 2)
resultField.value += results
} catch (err) {
console.error('Error getting offers:', err);
results = `\nError: ${err.message}\n`
resultField.value += results
throw err; // Re-throw the error to be handled by the caller
}
finally {
client.disconnect()
}
}// End of getOffers()
/***********************************
*********** Cancel Offer **********
**********************************/
async function cancelOffer() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}, canceling offer.===\n`
resultField.value = results
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
try {
// OfferSequence is the _seq_ value from getOffers.
const prepared = await client.autofill({
"TransactionType": "OfferCancel",
"Account": wallet.address,
"OfferSequence": parseInt(offerSequenceField.value)
})
const signed = wallet.sign(prepared)
const tx = await client.submitAndWait(signed.tx_blob)
results += "\nOffer canceled. Balance changes: \n" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
resultField.value = results
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
}
catch (err) {
console.error('Error canceling offer:', err);
results = `\nError: ${err.message}\n`
resultField.value += results
throw err; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
client.disconnect()
}
}// End of cancelOffer()

View File

@@ -0,0 +1,211 @@
<html>
<head>
<title>Create Permissioned Domain</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.2.5/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='credential-manager.js'></script>
<script src='permissioned-domain-manager.js'></script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Create Permissioned Domain</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Account receiving the credential.">
<label for="subjectField">Subject</label>
</span>
</td>
<td>
<input type="text" id="subjectField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="createCredential()">Create Credential</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Arbitrary data defining the type of credential this entry represents.">
<lable for="credentialTypeField">Credential Type</lable>
</span>
</td>
<td>
<input type="text" id="credentialTypeField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="The ledger entry ID of an existing permissioned domain to modify. If omitted, creates a new permissioned domain.">
<label for="domainIDField">Domain ID</label>
</span>
</td>
<td>
<input type="text" id="domainIDField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="createDomain()">Create Permissioned Domain</button>
<button type="button" onClick="deleteDomain()">Delete Permissioned Domain</button>
</td>
</tr>
<tr>
<td colspan="2">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,269 @@
<html>
<head>
<title>Create a Time-based Escrow</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='create-time-escrow.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Create a Time-based Escrow</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where the escrow is sent.">
<lable for="destinationField">Destination</lable>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="createTimeBasedEscrow()">Create Time-based Escrow</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Escrow finish time, in seconds.">
<lable for="escrowFinishTimeField">Escrow Finish Time</lable>
</span>
</td>
<td>
<input type="text" id="escrowFinishTimeField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getEscrows()">Get Escrows</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Escrow cancel time, in seconds.">
<lable for="escrowCancelTimeField">Escrow Cancel Time</lable>
</span>
</td>
<td>
<input type="text" id="escrowCancelTimeField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="finishTimeBasedEscrow()">Finish Time-based Escrow</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Escrow sequence number, used when finishing the escrow.">
<lable for="escrowSequenceNumberField">Escrow Sequence Number</lable>
</span>
</td>
<td>
<input type="text" id="escrowSequenceNumberField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="cancelEscrow()">Cancel Escrow</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Escrow owner, the account that created the escrow.">
<lable for="escrowOwnerField">Escrow Owner</lable>
</span>
</td>
<td>
<input type="text" id="escrowOwnerField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="getTransaction()">Get Transaction</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Transaction number, used with the Get Transaction button.">
<lable for="transactionField">Transaction</lable>
</span>
</td>
<td>
<input type="text" id="transactionField" size="40"></input>
<br>
</td>
<td>
</td>
</tr>
<tr>
<td colspan="2">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,177 @@
// *******************************************************
// ************* Add Seconds to Current Date *************
// *******************************************************
function addSeconds(numOfSeconds, date = new Date()) {
date.setSeconds(date.getSeconds() + numOfSeconds);
date = Math.floor(date / 1000)
date = date - 946684800
return date;
}
// *******************************************************
// ************* Create Time-based Escrow ****************
// *******************************************************
async function createTimeBasedEscrow() {
//-------------------------------------------- Prepare Finish and Cancel Dates
let escrow_finish_date = new Date()
let escrow_cancel_date = new Date()
escrow_finish_date = addSeconds(parseInt(escrowFinishTimeField.value))
escrow_cancel_date = addSeconds(parseInt(escrowCancelTimeField.value))
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}.===\n\n===Creating time-based escrow.===\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const sendAmount = amountField.value
const escrowTx = await client.autofill({
"TransactionType": "EscrowCreate",
"Account": wallet.address,
"Amount": xrpl.xrpToDrops(sendAmount),
"Destination": destinationField.value,
"FinishAfter": escrow_finish_date,
"CancelAfter": escrow_cancel_date
})
const signed = wallet.sign(escrowTx)
const tx = await client.submitAndWait(signed.tx_blob)
results += "\n===Success! === *** Save this sequence number: " + tx.result.tx_json.Sequence
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
resultField.value = results
}
catch (error) {
results += "\n===Error: " + error.message
resultField.value = results
}
finally {
client.disconnect()
}
} // End of createTimeEscrow()
// *******************************************************
// ***************** Finish Time- Based Escrow ***********
// *******************************************************
async function finishTimeBasedEscrow() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}. Finishing escrow.===\n`
resultField.value = results
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
try {
const prepared = await client.autofill({
"TransactionType": "EscrowFinish",
"Account": accountAddressField.value,
"Owner": escrowOwnerField.value,
"OfferSequence": parseInt(escrowSequenceNumberField.value)
})
const signed = wallet.sign(prepared)
const tx = await client.submitAndWait(signed.tx_blob)
results += "\n===Balance changes===" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
resultField.value = results
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
}
catch (error) {
results += "\n===Error: " + error.message + "==="
resultField.value = results
}
finally {
client.disconnect()
}
} // End of finishTimeBasedEscrow()
// *******************************************************
// ******************* Get Escrows ***********************
// *******************************************************
async function getEscrows() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `\n===Connected to ${net}.\nGetting account escrows.===\n`
resultField.value = results
try {
const escrow_objects = await client.request({
"id": 5,
"command": "account_objects",
"account": accountAddressField.value,
"ledger_index": "validated",
"type": "escrow"
})
results += JSON.stringify(escrow_objects.result, null, 2)
resultField.value = results
}
catch (error) {
results += "\nError: " + error.message
resultField.value = results
}
finally {
client.disconnect()
}
}
// *******************************************************
// ************** Get Transaction Info *******************
// *******************************************************
async function getTransaction() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `\n===Connected to ${net}.===\n===Getting transaction information.===\n`
resultField.value = results
try {
const tx_info = await client.request({
"id": 1,
"command": "tx",
"transaction": transactionField.value,
})
results += JSON.stringify(tx_info.result, null, 2)
resultField.value = results
}
catch (error) {
results += "\nError: " + error.message
resultField.value = results
}
finally {
client.disconnect()
}
} // End of getTransaction()
// *******************************************************
// ****************** Cancel Escrow **********************
// *******************************************************
async function cancelEscrow() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `\n===Connected to ${net}. Cancelling escrow.===`
resultField.value = results
try {
const prepared = await client.autofill({
"TransactionType": "EscrowCancel",
"Account": accountAddressField.value,
"Owner": escrowOwnerField.value,
"OfferSequence": parseInt(escrowSequenceNumberField.value)
})
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const signed = wallet.sign(prepared)
const tx = await client.submitAndWait(signed.tx_blob)
results += "\n===Balance changes: " +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
resultField.value = results
}
catch (error) {
results += "\n===Error: " + error.message
resultField.value = results
}
finally {
client.disconnect()
}
}

View File

@@ -0,0 +1,64 @@
// Create credential function
async function createCredential() {
let net = getNet()
const client = new xrpl.Client(net)
results = `\n\n===Creating Credential===\n\nConnecting to ${getNet()} ...`
updateResults()
await client.connect()
results = `\n\nConnected.`
updateResults()
// Gather transaction info
try {
// Get account wallet from seed
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
// Get subject
const subject = subjectField.value
// Get credential type - convert string to hex if needed
let credentialType = credentialTypeField.value;
if (!/^[0-9A-F]+$/i.test(credentialType)) {
let hex = '';
for (let i = 0; i < credentialType.length; i++) {
const charCode = credentialType.charCodeAt(i);
const hexCharCode = charCode.toString(16).padStart(2, '0');
hex += hexCharCode;
}
credentialType = hex.toUpperCase();
}
// Prepare transaction
const transaction = {
"TransactionType": "CredentialCreate",
"Account": wallet.address,
"Subject": subject,
"CredentialType": credentialType
}
results = `\n\n===Preparing and Sending Transaction===\n\n${JSON.stringify(transaction, null, 2)}`
updateResults()
// Submit transaction
const tx = await client.submitAndWait(transaction, {autofill: true, wallet: wallet})
if (tx.result.meta.TransactionResult == "tesSUCCESS") {
// Parse for credential info
const parsedResponse = JSON.parse(JSON.stringify(tx.result.meta.AffectedNodes, null, 2))
const credentialInfo = parsedResponse.find( node => node.CreatedNode && node.CreatedNode.LedgerEntryType === "Credential" )
results = `\n\n===Create Credential Result===\n\n${JSON.stringify(credentialInfo.CreatedNode, null, 2)}`
} else {
results = `\n\n===Error===\n\n${JSON.stringify(tx.result.meta.TransactionResult, null, 2)}: Check codes at https://xrpl.org/docs/references/protocol/transactions/types/credentialcreate#error-cases`
}
updateResults()
} catch (error) {
results = `\n\n===Error===\n\n${error}`
updateResults()
}
client.disconnect()
}

View File

@@ -0,0 +1,24 @@
const cc = require('five-bells-condition');
const crypto = require('crypto');
// 1. Generate a random 32-byte seed
const preimageData = crypto.randomBytes(32);
// 2. Create a PreimageSha256 fulfillment object
const fulfillment = new cc.PreimageSha256();
// 3. Set the preimage
fulfillment.setPreimage(preimageData);
// 4. Generate the condition (binary)
const conditionBinary = fulfillment.getConditionBinary();
// 5. Generate the fulfillment (binary)
const fulfillmentBinary = fulfillment.serializeBinary();
// Convert to hex for easier use
const conditionHex = conditionBinary.toString('hex').toUpperCase();
const fulfillmentHex = fulfillmentBinary.toString('hex').toUpperCase();
console.log('Condition (hex):', conditionHex);
console.log('Fulfillment (hex):', fulfillmentHex);

View File

@@ -0,0 +1,150 @@
body {
font-family: "Inter", sans-serif;
padding: 20px;
background: #abe2ff;
}
h1 {
font-weight: bold;
}
td {
padding-left: 25px;
vertical-align: top;
}
input,
button {
padding: 6px;
margin-bottom: 8px;
border: none
}
input:read-only {
background-color:rgb(11, 96, 132);
color:white;
border: 0;
}
button {
font-weight: bold;
font-family: "Work Sans", sans-serif;
background-color: #006aff;
-webkit-text-fill-color: white;
}
button:hover {
background-color: #0555c5;
cursor: pointer;
}
td {
vertical-align: middle;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 30px;
height: 16px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 4px;
bottom: 2px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
/* Rounded sliders */
.slider.round {
border-radius: 17px;
}
.slider.round:before {
border-radius: 50%;
}
.tooltip {
position: relative;
border-bottom: 1px dotted black;
}
.tooltip:before {
content: attr(tooltip-data);
position: absolute;
width: 250px;
background-color: #006aff;
color: #fff;
text-align: center;
padding: 15px;
line-height: 1.1;
border-radius: 5px;
z-index: 1;
opacity: 0;
transition: opacity .5s;
bottom: 125%;
left: 50%;
margin-left: -60px;
font-size: 0.70em;
visibility: hidden;
}
.tooltip:after {
content: "";
position: absolute;
bottom: 75%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
opacity: 0;
transition: opacity .5s;
border-color: #000 transparent transparent transparent;
visibility: hidden;
}
.tooltip:hover:before,
.tooltip:hover:after {
opacity: 1;
visibility: visible;
}

View File

@@ -0,0 +1,127 @@
/// Create permissioned domain
async function createDomain() {
let net = getNet()
const client = new xrpl.Client(net)
results = `\n\n===Creating Permissioned Domain===\n\nConnecting to ${getNet()} ...`
updateResults()
await client.connect()
results = `\n\nConnected.`
updateResults()
// Gather transaction info
try {
// Get account wallet from seed
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
// Get Domain ID
const domainID = domainIDField.value
// Get credential type - convert string to hex if needed
let credentialType = credentialTypeField.value;
if (!/^[0-9A-F]+$/i.test(credentialType)) {
let hex = '';
for (let i = 0; i < credentialType.length; i++) {
const charCode = credentialType.charCodeAt(i);
const hexCharCode = charCode.toString(16).padStart(2, '0');
hex += hexCharCode;
}
credentialType = hex.toUpperCase();
}
// Prepare transaction
const transaction = {
"TransactionType": "PermissionedDomainSet",
"Account": wallet.address,
"AcceptedCredentials": [
{
"Credential": {
"Issuer": wallet.address,
"CredentialType": credentialType
}
}
]
}
if (domainID) {
transaction.DomainID = domainID
}
results = `\n\n===Preparing and Sending Transaction===\n\n${JSON.stringify(transaction, null, 2)}`
updateResults()
// Submit transaction
const tx = await client.submitAndWait(transaction, {autofill: true, wallet: wallet})
if (tx.result.meta.TransactionResult == "tesSUCCESS") {
// Parse for domain info
if (domainID) {
results = `\n\n===Create Permissioned Domain Result===\n\n${JSON.stringify(tx.result.tx_json, null, 2)}`
} else {
const parsedResponse = JSON.parse(JSON.stringify(tx.result.meta.AffectedNodes, null, 2))
const domainInfo = parsedResponse.find( node => node.CreatedNode && node.CreatedNode.LedgerEntryType === "PermissionedDomain" )
results = `\n\n===Create Permissioned Domain Result===\n\n${JSON.stringify(domainInfo.CreatedNode, null, 2)}`
}
} else {
results = `\n\n===Error===\n\n${JSON.stringify(tx.result.meta.TransactionResult, null, 2)}: Check codes at https://xrpl.org/docs/references/protocol/transactions/types/permissioneddomainset#error-cases`
}
updateResults()
} catch (error) {
results = `\n\n===Error===\n\n${error}`
updateResults()
}
client.disconnect()
}
// End create permissioned domain
// Delete permissioned domain
async function deleteDomain() {
let net = getNet()
const client = new xrpl.Client(net)
results = `\n\n===Delete Permissioned Domain===\n\nConnecting to ${getNet()} ...`
updateResults()
await client.connect()
results = `\n\nConnected.`
updateResults()
// Get delete domain transaction info
try {
// Get account wallet from seed
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
// Get Domain ID
const domainID = domainIDField.value
// Prepare transaction
const transaction = {
"TransactionType": "PermissionedDomainDelete",
"Account": wallet.address,
"DomainID": domainID
}
results = `\n\n===Preparing and Sending Transaction===\n\n${JSON.stringify(transaction, null, 2)}`
updateResults()
// Submit delete domain transaction
const tx = await client.submitAndWait(transaction, {autofill: true, wallet: wallet})
if (tx.result.meta.TransactionResult == "tesSUCCESS") {
results = `\n\n===Delete Permissioned Domain Result===\n\nSuccessfully deleted the permissioned domain.`
} else {
results = `\n\n===Error===\n\n${JSON.stringify(tx.result.meta.TransactionResult, null, 2)}: Check codes at https://xrpl.org/docs/references/protocol/transactions/types/permissioneddomaindelete#error-cases`
}
updateResults()
} catch (error) {
results = `\n\n===Error===\n\n${error}`
updateResults()
}
client.disconnect()
}

View File

@@ -0,0 +1,247 @@
<html>
<head>
<title>Send Checks</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='send-xrp.js'></script>
<script src='send-currency.js'></script>
<script src='send-checks.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Send Checks</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Currency code for the check.">
<lable for="currencyField">Currency Code</lable>
</span>
</td>
<td>
<input type="text" id="currencyField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="sendCheck()">Send Check</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuing account for the currency.">
<lable for="issuerField">Issuer</lable>
</span>
</td>
<td>
<input type="text" id="issuerField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="cashCheck()">Cash Check</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getChecks()">Get Checks</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where XRP is sent.">
<lable for="destinationField">Destination</lable>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="cancelCheck()">Cancel Check</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Check ID.">
<lable for="checkIdField">Check ID</lable>
</span>
</td>
<td>
<input type="text" id="checkIdField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getTokenBalance()">Get Token Balance</button>
</td>
</tr>
<tr>
<td colspan="2">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,152 @@
// *******************************************************
// ***************** Send Check **************************
// *******************************************************
async function sendCheck() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
results = `\n===Connected to ${net}.===\n===Sending check.===\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
let check_amount = amountField.value
if (currencyField.value != "XRP") {
check_amount = {
"currency": currencyField.value,
"value": amountField.value,
"issuer": wallet.address
}
}
const send_check_tx = {
"TransactionType": "CheckCreate",
"Account": wallet.address,
"SendMax": check_amount,
"Destination": destinationField.value
}
const check_prepared = await client.autofill(send_check_tx)
const check_signed = wallet.sign(check_prepared)
results = '\n===Sending ' + amountField.value + ' ' + currencyField.
value + ' to ' + destinationField.value + '.===\n'
resultField.value += results
const check_result = await client.submitAndWait(check_signed.tx_blob)
if (check_result.result.meta.TransactionResult == "tesSUCCESS") {
results += '===Transaction succeeded===\n\n'
resultField.value += JSON.stringify(check_result.result, null, 2)
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
}
}
catch (error) {
results = `Error sending transaction: ${error}`
resultField.value += results
}
finally {
client.disconnect()
}
} // end of sendCheck()
// *******************************************************
// ********************* Get Checks **********************
// *******************************************************
async function getChecks() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `\n===Connected to ${net}.===\n===Getting account checks.===\n\n`
resultField.value = results
try {
const check_objects = await client.request({
"id": 5,
"command": "account_objects",
"account": accountAddressField.value,
"ledger_index": "validated",
"type": "check"
})
resultField.value += JSON.stringify(check_objects.result, null, 2)
} catch (error) {
results = `Error getting checks: ${error}`
resultField.value += results
}
finally {
client.disconnect()
}
} // End of getChecks()
// *******************************************************
// ******************** Cash Check **********************
// *******************************************************
async function cashCheck() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
results = `\n===Connected to ${net}.===\n===Cashing check.===\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
let check_amount = amountField.value
if (currencyField.value != "XRP") {
check_amount = {
"value": amountField.value,
"currency": currencyField.value,
"issuer": issuerField.value
}
}
const cash_check_tx = {
"TransactionType": "CheckCash",
"Account": wallet.address,
"Amount": check_amount,
"CheckID": checkIdField.value
}
const cash_prepared = await client.autofill(cash_check_tx)
const cash_signed = wallet.sign(cash_prepared)
results = ' Receiving ' + amountField.value + ' ' + currencyField.value + '.\n'
resultField.value += results
const check_result = await client.submitAndWait(cash_signed.tx_blob)
if (check_result.result.meta.TransactionResult == "tesSUCCESS") {
results = '===Transaction succeeded===\n' + JSON.stringify(check_result.result, null, 2)
resultField.value += results
}
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
} catch (error) {
results = `Error sending transaction: ${error}`
resultField.value += results
}
finally {
client.disconnect()
}
} // end of cashCheck()
// *******************************************************
// **************** Cancel Check *************************
// *******************************************************
async function cancelCheck() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
results = `\n===Connected to ${net}.===\n===Cancelling check.===\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const cancel_check_tx = {
"TransactionType": "CheckCancel",
"Account": wallet.address,
"CheckID": checkIdField.value
}
const cancel_prepared = await client.autofill(cancel_check_tx)
const cancel_signed = wallet.sign(cancel_prepared)
const check_result = await client.submitAndWait(cancel_signed.tx_blob)
if (check_result.result.meta.TransactionResult == "tesSUCCESS") {
results += `===Transaction succeeded===\n${check_result.result.meta.TransactionResult}`
resultField.value = results
}
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
} catch (error) {
results = `Error sending transaction: ${error}`
resultField.value += results
}
finally {
client.disconnect()
}
} // end of cancelCheck()

View File

@@ -0,0 +1,229 @@
<html>
<head>
<title>Send Currency</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='send-xrp.js'></script>
<script src='send-currency.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Send Currency</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Currency code for the trust line.">
<lable for="currencyField">Currency Code</lable>
</span>
</td>
<td>
<input type="text" id="currencyField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="createTrustLine()">Create Trust Line</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuing account for the currency.">
<lable for="issuerField">Issuer</lable>
</span>
</td>
<td>
<input type="text" id="issuerField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="sendCurrency()">Send Currency</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getTokenBalance()">Get Token Balance</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where XRP is sent.">
<lable for="destinationField">Destination</lable>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td colspan="2">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,96 @@
// *******************************************************
// ***************** Create TrustLine ********************
// *******************************************************
async function createTrustLine() {
const net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = "\nConnected. Creating trust line.\n"
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const trustSet_tx = {
"TransactionType": "TrustSet",
"Account": accountAddressField.value,
"LimitAmount": {
"currency": currencyField.value,
"issuer": issuerField.value,
"value": amountField.value
}
}
const ts_prepared = await client.autofill(trustSet_tx)
const ts_signed = wallet.sign(ts_prepared)
resultField.value = results
const ts_result = await client.submitAndWait(ts_signed.tx_blob)
if (ts_result.result.meta.TransactionResult == "tesSUCCESS") {
results += '\n===Trustline established between account\n' +
accountAddressField.value + "\nand account\n" + issuerField.value + '.'
resultField.value = results
} else {
results += `\n===Transaction failed: ${ts_result.result.meta.TransactionResult}`
resultField.value = results
}
}
catch (error) {
console.error('Error creating trust line:', error);
results += `\n===Error: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
await client.disconnect();
}
} //End of createTrustline()
// *******************************************************
// *************** Send Issued Currency ******************
// *******************************************************
async function sendCurrency() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
resultField.value = results
await client.connect()
results += '\nConnected.'
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const send_currency_tx = {
"TransactionType": "Payment",
"Account": wallet.address,
"Amount": {
"currency": currencyField.value,
"value": amountField.value,
"issuer": issuerField.value
},
"Destination": destinationField.value
}
const pay_prepared = await client.autofill(send_currency_tx)
const pay_signed = wallet.sign(pay_prepared)
results += `\n\n===Sending ${amountField.value} ${currencyField.value} to ${destinationField.value} ...`
resultField.value = results
const pay_result = await client.submitAndWait(pay_signed.tx_blob)
if (pay_result.result.meta.TransactionResult == "tesSUCCESS") {
results += '\n===Transaction succeeded.'
resultField.value = results
getTokenBalance()
} else {
results += `\n===Transaction failed: ${pay_result.result.meta.TransactionResult}\n`
resultField.value = results
}
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
}
catch (error) {
console.error('Error sending transaction:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
await client.disconnect();
}
} // end of sendCurrency()

View File

@@ -0,0 +1,218 @@
<html>
<head>
<title>Send MPT</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='send-mpt.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Send MPT</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuance ID of the MPT you want to trade.">
<lable for="mptIdField">MPT Issuance ID</lable>
</span>
</td>
<td>
<input type="text" id="mptIdField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="authorizeMPT()">Authorize MPT</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Number of MPTs to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="sendMPT()">Send MPT</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address for MPT transfer.">
<lable for="destinationField">Destination</lable>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getMPTs()">Get MPTs</button>
</td>
</tr>
<tr>
<td colspan="2">
<p align="right">
<textarea id="resultField" cols="80" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br/>
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
let radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,113 @@
// *******************************************************
// ********************* Send MPT ************************
// *******************************************************
async function sendMPT() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}. Sending MPT.===\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const mpt_issuance_id = mptIdField.value
const mpt_quantity = amountField.value
const send_mpt_tx = {
"TransactionType": "Payment",
"Account": wallet.address,
"Amount": {
"mpt_issuance_id": mpt_issuance_id,
"value": mpt_quantity,
},
"Destination": destinationField.value,
}
const pay_prepared = await client.autofill(send_mpt_tx)
const pay_signed = wallet.sign(pay_prepared)
results = `\n===Sending ${mpt_quantity} ${mpt_issuance_id} to ${destinationField.value} ...`
resultField.value += results
const pay_result = await client.submitAndWait(pay_signed.tx_blob)
results = '\n\n===Transaction succeeded.\n'
results += JSON.stringify(pay_result.result, null, 2)
resultField.value += results
} catch (error) {
results = `Error sending MPT: ${error}`
resultField.value += results
}
finally {
client.disconnect()
}
} // end of sendMPT()
// *******************************************************
// ******************** Get MPTs *************************
// *******************************************************
async function getMPTs() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = ''
resultField.value = `===Connected to ${net}. Getting MPTs.===`
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const mpts = await client.request({
command: "account_objects",
account: wallet.address,
ledger_index: "validated",
type: "mptoken"
})
let JSONString = JSON.stringify(mpts.result, null, 2)
let JSONParse = JSON.parse(JSONString)
let numberOfMPTs = JSONParse.account_objects.length
let x = 0
while (x < numberOfMPTs){
results += "\n\n===MPT Issuance ID: " + JSONParse.account_objects[x].MPTokenIssuanceID
+ "\n===MPT Amount: " + JSONParse.account_objects[x].MPTAmount
x++
}
results += "\n\n" + JSONString
resultField.value += results
} catch (error) {
results = `===Error getting MPTs: ${error}`
resultField.value += results
}
finally {
client.disconnect()
}
} // End of getMPTs()
// **********************************************************************
// ****** MPTAuthorize Transaction ***************************************
// **********************************************************************
async function authorizeMPT() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}. Authorizing MPT.===\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const mpt_issuance_id = mptIdField.value
const auth_mpt_tx = {
"TransactionType": "MPTokenAuthorize",
"Account": wallet.address,
"MPTokenIssuanceID": mpt_issuance_id,
}
const auth_prepared = await client.autofill(auth_mpt_tx)
const auth_signed = wallet.sign(auth_prepared)
results += `\n\n===Sending authorization.===\n`
resultField.value = results
const auth_result = await client.submitAndWait(auth_signed.tx_blob)
results = '\n===Transaction succeeded===\n\n'
resultField.value += results
results += `\n\n` + JSON.stringify(auth_result.result, null, 2)
} catch (error) {
results = `===Error authorizing MPT: ${error}`
resultField.value = results
} finally {
resultField.value = results
}
client.disconnect()
} // end of MPTAuthorize()

View File

@@ -0,0 +1,37 @@
// *******************************************************
// ******************** Send XRP *************************
// *******************************************************
async function sendXRP() {
const net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}.===\n\nSending XRP.\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const sendAmount = amountField.value
// -------------------------------------------------------- Prepare transaction
const prepared_tx = await client.autofill({
"TransactionType": "Payment",
"Account": wallet.address,
"Amount": xrpl.xrpToDrops(sendAmount),
"Destination": destinationField.value
})
// ------------------------------------------------- Sign prepared instructions
const signed = wallet.sign(prepared_tx)
// -------------------------------------------------------- Submit signed blob
const tx = await client.submitAndWait(signed.tx_blob)
results += JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
resultField.value = results
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
} catch (error) {
console.error('Error sending transaction:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
await xrplClient.disconnect();
}
} // End of sendXRP()

View File

@@ -0,0 +1,209 @@
// ******************************************************
// ************* Get the Preferred Network **************
// ******************************************************
function getNet() {
let net
if (document.getElementById("tn").checked) net = "wss://s.altnet.rippletest.net:51233/"
if (document.getElementById("dn").checked) net = "wss://s.devnet.rippletest.net:51233/"
return net
} // End of getNet()
// *******************************************************
// ************* Get Account *****************************
// *******************************************************
async function getAccount() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
resultField.value = `===Getting Account===\n\nConnected to ${net}.`
try {
let faucetHost = null
const my_wallet = (await client.fundWallet(null, { faucetHost})).wallet
const newAccount = [my_wallet.address, my_wallet.seed]
return newAccount
}
catch (error) {
console.error('===Error getting account:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
if (client && client.isConnected()) {
await client.disconnect();
}
}
} // End of getAccount()
async function getNewAccount1() {
account1address.value = "=== Getting new account. ===\n\n"
account1seed.value = ""
const accountInfo= await getAccount()
account1address.value = accountInfo[0]
account1seed.value = accountInfo[1]
}
async function getNewAccount2() {
account2address.value = "=== Getting new account. ===\n\n"
account2seed.value = ""
const accountInfo= await getAccount()
account2address.value = accountInfo[0]
account2seed.value = accountInfo[1]
}
// *****************************************************
// ********** Get Account from Seed ********************
// *****************************************************
async function getAccountFromSeed(my_seed) {
const net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = '===Finding wallet.===\n\n'
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(my_seed)
const address = wallet.address
results += "===Wallet found.===\n\n"
results += "Account address: " + address + "\n\n"
resultField.value = results
return (address)
}
catch (error) {
console.error('===Error getting account from seed:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
await client.disconnect();
}
} // End of getAccountFromSeed()
// *****************************************************
// ********** Get Account from Seed1 *******************
// *****************************************************
async function getAccountFromSeed1() {
account1address.value = await getAccountFromSeed(account1seed.value)
}
// *****************************************************
// ********** Get Account from Seed2 *******************
// *****************************************************
async function getAccountFromSeed2() {
account2address.value = await getAccountFromSeed(account2seed.value)
}
// *****************************************************
// ************ Gather Account Info ********************
// *****************************************************
function gatherAccountInfo() {
let accountData = account1name.value + "\n" + account1address.value + "\n" + account1seed.value + "\n"
accountData += account2name.value + "\n" + account2address.value + "\n" + account2seed.value
resultField.value = accountData
}
// *****************************************************
// ********** Distribute Account Info ******************
// *****************************************************
function distributeAccountInfo() {
let accountInfo = resultField.value.split("\n")
account1name.value = accountInfo[0]
account1address.value = accountInfo[1]
account1seed.value = accountInfo[2]
account2name.value = accountInfo[3]
account2address.value = accountInfo[4]
account2seed.value = accountInfo[5]
}
// *****************************************************
// ************ Populate Active Form 1 *****************
// *****************************************************
function populate1() {
accountNameField.value = account1name.value
accountAddressField.value = account1address.value
accountSeedField.value = account1seed.value
getXrpBalance()
}
// *****************************************************
// ************ Populate Active Form 2 *****************
// *****************************************************
function populate2() {
accountNameField.value = account2name.value
accountAddressField.value = account2address.value
accountSeedField.value = account2seed.value
getXrpBalance()
}
// *******************************************************
// **************** Get XRP Balance *********************
// *******************************************************
async function getXrpBalance() {
const net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `\n===Getting XRP balance...===\n\n`
resultField.value = results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const balance = await client.getXrpBalance(wallet.address)
results += accountNameField.value + " current XRP balance: " + balance + "\n\n"
xrpBalanceField.value = await client.getXrpBalance(accountAddressField.value)
resultField.value = results
}
catch (error) {
console.error('Error getting XRP balance:', error);
results += `\nError: ${error.message}\n`
resultField.value = results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
await client.disconnect();
}
} // End of getXrpBalance()
// *******************************************************
// ************** Get Token Balance *********************
// *******************************************************
async function getTokenBalance() {
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = `===Connected to ${net}.===\n===Getting account token balance...===\n\n`
resultField.value += results
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const balance = await client.request({
command: "gateway_balances",
account: wallet.address,
ledger_index: "validated",
})
results = accountNameField.value + "\'s token balance(s): " + JSON.stringify(balance.result, null, 2) + "\n"
resultField.value += results
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
}
catch (error) {
console.error('Error getting token balance:', error);
results = `\nError: ${error.message}\n`
resultField.value += results
throw error; // Re-throw the error to be handled by the caller
}
finally {
// Disconnect from the client
await client.disconnect();
}
} // End of getTokenBalance()

View File

@@ -0,0 +1,340 @@
<html>
<head>
<title>Authorize Minter of NFTs</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='transaction-support.js'></script>
<script src='mint-nfts.js'></script>
<script src='authorized-minter.js'></script>
</head>
<body>
<h1>Authorize Minter of NFTs</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label
for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
<td rowspan="4" align="center">
<p>
<img id="nftImage"
src="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"
width="150" height="150">
</td>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT configuration flags.">
<label for="flagsField">Flags</label>
</span>
</td>
<td>
<input type="text" id="flagsField" size="40"></input>
</td>
<td align="right">
<span class="tooltip" tooltip-data="URL to the stored NFT.">
<label for="nftURLfield">NFT URL</label>
</span>&nbsp;&nbsp;
<input type="text" id="nftURLfield" size="30"
value="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Percentage of sale price collected by the issuer when the NFT is sold. Enter a value from 0 to 50000, where 1000=1%.">
<label for="transferFeeField">Transfer Fee</label>
</span>
<p id="error-message"></p>
</td>
<td>
<input type="text" id="transferFeeField" size="40"></input>
</td>
<td>
<button type="button" onClick="mintNFT()">Mint NFT</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT Taxon. Integer value used to identify NFTs minted in a series or collection. This value is required. Set it to 0 if you have no use for it.">
<label for="nftTaxonField">NFT Taxon</label>
</span>
</td>
<td>
<input type="text" id="nftTaxonField" size="40" value="0"></input>
</td>
<td>
<button type="button" onClick="getNFTs()">Get NFTs</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Currency for the offer.">
<label for="currencyField">Currency</label>
</span>
</td>
<td>
<input type="text" id="currencyField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="burnNFT()">Burn NFT</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuer of the currency used.">
<label for="issuerField">Issuer</label>
</span>
</td>
<td>
<input type="text" id="issuerField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
</td>
<td>
<button type="button" onClick="authorizeMinter()">Authorize Minter</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where XRP is sent.">
<label for="destinationField">Destination</label>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="mintOther()">Mint Other</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Number of days the offer is valid.">
<label for="expirationField">Expiration (days)</label>
</span>
</td>
<td>
<input type="text" id="expirationField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT ID, used to transfer or burn the NFT after it is created.">
<label for="nftIdField">NFT ID</label>
</span>
</td>
<td>
<input type="text" id="nftIdField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Account address that is authorized to mint NFTs for this account.">
<label for="authorizedMinterField">Authorized Minter</label>
</span>
</td>
<td>
<input type="text" id="authorizedMinterField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Account that is the original issuer of the NFT.">
<label for="nftIssuerField">NFT Issuer</label>
</span>
</td>
<td>
<input type="text" id="nftIssuerField" size="40"></input>
</td>
</tr>
<tr>
<td colspan="2">
<p align="left">
<textarea id="resultField" cols="75" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br />
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const imageURLInput = document.getElementById('nftURLfield'); // Correct ID to nftURLfield
const displayImage = document.getElementById('nftImage');
const errorMessage = document.getElementById('error-message');
if (imageURLInput) {
imageURLInput.addEventListener('change', () => {
const newURL = imageURLInput.value;
displayImage.src = ''; // Clear previous image
errorMessage.style.display = 'none';
try {
new URL(newURL);
} catch (_) {
errorMessage.textContent = 'Invalid URL. Please enter a valid URL, including "https://" or "http://".';
errorMessage.style.display = 'block';
return;
}
displayImage.onload = () => {
// Image loaded. You might add a console log here, or update UI.
console.log(`Image loaded from: ${newURL}`);
};
displayImage.onerror = () => {
errorMessage.textContent = 'Error loading image from the provided URL.';
errorMessage.style.display = 'block';
displayImage.src = ''; // Clear the image on error
};
displayImage.src = newURL; // Load the image
});
}
});
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function () {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,97 @@
// *******************************************************
// ************ Authorize Minter ***********************
// *******************************************************
async function authorizeMinter() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
const net = getNet();
const client = new xrpl.Client(net);
let results = `\n=== Connected. Authorizing Minter. ===`;
resultField.value = results;
try {
await client.connect();
tx_json = {
"TransactionType": "AccountSet",
"Account": wallet.address,
"NFTokenMinter": authorizedMinterField.value,
"SetFlag": xrpl.AccountSetAsfFlags.asfAuthorizedNFTokenMinter
}
const prepared = await client.autofill(tx_json)
const signed = wallet.sign(prepared)
const result = await client.submitAndWait(signed.tx_blob)
results += '\nAccount setting succeeded.\n'
results += JSON.stringify(result, null, 2)
resultField.value = results
} catch (error) {
console.error("Error setting minter:", error);
results = `\n\n=== Error setting minter: ${error.message}`;
resultField.value += results;
} finally {
if (client && client.isConnected()) {
await client.disconnect();
}
}
} // End of authorizeMinter()
// *******************************************************
// **************** Mint Other *************************
// *******************************************************
async function mintOther() {
let results = 'Connecting to ' + getNet() + '....'
resultField.value = results
const net = getNet()
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
const client = new xrpl.Client(net)
try {
await client.connect()
results += '\nConnected. Minting NFT.'
resultField.value = results
// ------------------------------------------------------------------------
const tx_json = {
"TransactionType": "NFTokenMint",
"Account": wallet.classicAddress,
"URI": xrpl.convertStringToHex(nftURLfield.value),
"Flags": parseInt(flagsField.value),
"TransferFee": parseInt(transferFeeField.value),
"Issuer": nftIssuerField.value,
"NFTokenTaxon": nftTaxonField.value //Required, but if you have no use for it, set to zero.
}
if (amountField.value) {
tx_json.Amount = configureAmount(amountField.value);
}
if (expirationField.value) {
tx_json.Expiration = configureExpiration(expirationField.value);
}
if (destinationField.value) {
tx_json.Destination = destinationField.value;
}
// ----------------------------------------------------- Submit transaction
const tx = await client.submitAndWait(tx_json, { wallet: wallet })
const nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress
})
// ------------------------------------------------------- Report results
results += '\n\n=== Transaction result: ' + tx.result.meta.TransactionResult
results += '\n\n=== NFTs: ' + JSON.stringify(nfts, null, 2)
resultField.value = results + (await client.getXrpBalance(wallet.address))
} catch (error) {
results += '\n\nAn error occurred: ' + error.message
console.error(error) // Log the error for debugging
resultField.value = results
} finally {
if (client.isConnected()) { // Check if the client is connected before attempting to disconnect
client.disconnect()
results += '\nDisconnected from XRPL.'
resultField.value = results
}
}
} //End of mintOther()

View File

@@ -0,0 +1,320 @@
<html>
<head>
<title>Batch Mint NFTs</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='transaction-support.js'></script>
<script src='mint-nfts.js'></script>
<script src="batch-minting.js"></script>
</head>
<body>
<h1>Batch Mint NFTs</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label
for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
<td rowspan="4" align="center">
<p>
<img id="nftImage"
src="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"
width="150" height="150">
</td>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT configuration flags.">
<label for="flagsField">Flags</label>
</span>
</td>
<td>
<input type="text" id="flagsField" size="40"></input>
</td>
<td align="right">
<span class="tooltip" tooltip-data="URL to the stored NFT.">
<label for="nftURLfield">NFT URL</label>
</span>&nbsp;&nbsp;
<input type="text" id="nftURLfield" size="30"
value="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Percentage of sale price collected by the issuer when the NFT is sold. Enter a value from 0 to 50000, where 1000=1%.">
<label for="transferFeeField">Transfer Fee</label>
</span>
<p id="error-message"></p>
</td>
<td>
<input type="text" id="transferFeeField" size="40"></input>
</td>
<td>
<button type="button" onClick="batchMintNFTs()">Batch Mint NFTs</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT Taxon. Integer value used to identify NFTs minted in a series or collection. This value is required. Set it to 0 if you have no use for it.">
<label for="nftTaxonField">NFT Taxon</label>
</span>
</td>
<td>
<input type="text" id="nftTaxonField" size="40" value="0"></input>
</td>
<td>
<button type="button" onClick="getBatchNFTs()">Get Batch NFTs</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Currency for the offer.">
<label for="currencyField">Currency</label>
</span>
</td>
<td>
<input type="text" id="currencyField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuer of the currency used.">
<label for="issuerField">Issuer</label>
</span>
</td>
<td>
<input type="text" id="issuerField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where XRP is sent.">
<label for="destinationField">Destination</label>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Number of days the offer is valid.">
<label for="expirationField">Expiration (days)</label>
</span>
</td>
<td>
<input type="text" id="expirationField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Number of NFTs to produce in a batch.">
<label for="nftCountField">NFT Count</label>
</span>
</td>
<td>
<input type="text" id="nftCountField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT ID, used to transfer or burn the NFT after it is created.">
<label for="nftIdField">NFT ID</label>
</span>
</td>
<td>
<input type="text" id="nftIdField" size="40"></input>
</td>
</tr> <tr>
<td colspan="2">
<p align="left">
<textarea id="resultField" cols="75" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br />
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const imageURLInput = document.getElementById('nftURLfield'); // Correct ID to nftURLfield
const displayImage = document.getElementById('nftImage');
const errorMessage = document.getElementById('error-message');
if (imageURLInput) {
imageURLInput.addEventListener('change', () => {
const newURL = imageURLInput.value;
displayImage.src = ''; // Clear previous image
errorMessage.style.display = 'none';
try {
new URL(newURL);
} catch (_) {
errorMessage.textContent = 'Invalid URL. Please enter a valid URL, including "https://" or "http://".';
errorMessage.style.display = 'block';
return;
}
displayImage.onload = () => {
// Image loaded. You might add a console log here, or update UI.
console.log(`Image loaded from: ${newURL}`);
};
displayImage.onerror = () => {
errorMessage.textContent = 'Error loading image from the provided URL.';
errorMessage.style.display = 'block';
displayImage.src = ''; // Clear the image on error
};
displayImage.src = newURL; // Load the image
});
}
});
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function () {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,272 @@
// *******************************************************
// ****************** Batch Mint ***********************
// *******************************************************
async function batchMintNFTs() {
let client; // Declare client here so it's accessible in finally block
try {
//--------------------- Connect to the XRP Ledger and get the account wallet.
let net = getNet();
client = new xrpl.Client(net); // Assign client
results = 'Connecting to ' + getNet() + '....';
resultField.value = results;
await client.connect();
results += '\nConnected, finding wallet.';
resultField.value = results;
let wallet;
try {
wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
} catch (error) {
results += '\nError: Invalid account seed. Please check your seed.';
resultField.value = results;
return; // Stop execution if wallet cannot be derived
}
resultField.value = results;
//----------------- Get account information, particularly the Sequence number.
let account_info;
try {
account_info = await client.request({
"command": "account_info",
"account": wallet.address
});
} catch (error) {
results += `\nError retrieving account info for ${wallet.address}: ${error.message}`;
resultField.value = results;
return;
}
let my_sequence = account_info.result.account_data.Sequence;
results += "\n\nSequence Number: " + my_sequence + "\n\n";
resultField.value = results;
/* ###################################
Create ticket numbers for the batch
Without tickets, if one transaction fails, all others in the batch fail.
With tickets, there can be failures, but the rest will continue, and you
can investigate any problems afterward.
*/
//---------------------- Parse the requested number from nftCountField.
const nftCount = parseInt(nftCountField.value);
if (isNaN(nftCount) || nftCount <= 0) {
results += '\nError: Please enter a valid number of NFTs to mint.';
resultField.value = results;
return;
}
//-------------------------------------------- Create the transaction hash.
let ticketTransaction;
try {
ticketTransaction = await client.autofill({
"TransactionType": "TicketCreate",
"Account": wallet.address,
"TicketCount": nftCount,
"Sequence": my_sequence
});
} catch (error) {
results += `\nError autofilling ticket creation transaction: ${error.message}`;
resultField.value = results;
return;
}
//---------------------------------------------------- Sign the transaction.
const signedTransaction = wallet.sign(ticketTransaction);
//-------------------------- Submit the transaction and wait for the result.
let tx;
try {
tx = await client.submitAndWait(signedTransaction.tx_blob);
} catch (error) {
results += `\nError submitting ticket creation transaction: ${error.message}`;
resultField.value = results;
return;
}
if (tx.result.meta.TransactionResult !== 'tesSUCCESS') {
results += `\nError creating tickets. Transaction failed with result: ${tx.result.meta.TransactionResult}`;
resultField.value = results;
return;
}
results += `\nTickets created successfully. Transaction result: ${tx.result.meta.TransactionResult}\n\n`;
resultField.value = results;
let response;
try {
response = await client.request({
"command": "account_objects",
"account": wallet.address,
"type": "ticket"
});
} catch (error) {
results += `\nError retrieving account tickets: ${error.message}`;
resultField.value = results;
return;
}
//------------------------------------ Populate the tickets array variable.
let tickets = [];
if (response.result.account_objects && response.result.account_objects.length > 0) {
for (let i = 0; i < nftCount; i++) {
if (response.result.account_objects[i]) {
tickets[i] = response.result.account_objects[i].TicketSequence;
} else {
results += `\nWarning: Fewer tickets found than requested. Expected ${nftCount}, found ${response.result.account_objects.length}.`;
resultField.value = results;
break; // Exit loop if tickets run out
}
}
} else {
results += '\nError: No tickets found for the account.';
resultField.value = results;
return;
}
//-------------------------------------------------------- Report progress.
results += "Tickets generated, minting NFTs.\n\n";
resultField.value = results;
// ###################################
// Mint NFTs
let mintedNFTsCount = 0;
for (let i = 0; i < tickets.length; i++) {
const transactionParams = {
"TransactionType": "NFTokenMint",
"Account": wallet.classicAddress,
"URI": xrpl.convertStringToHex(nftURLfield.value),
"Flags": parseInt(flagsField.value),
"TransferFee": parseInt(transferFeeField.value),
"Sequence": 0, // Sequence is 0 when using TicketSequence
"TicketSequence": tickets[i],
"LastLedgerSequence": null, // Optional, can be used for time limits
"NFTokenTaxon": nftTaxonField.value,
};
// Add optional fields
if (amountField.value) {
transactionParams.Amount = configureAmount(amountField.value);
}
if (expirationField.value) {
transactionParams.Expiration = configureExpiration(expirationField.value);
}
if (destinationField.value) {
transactionParams.Destination = destinationField.value;
}
try {
const mintTx = await client.submit(transactionParams, {
wallet: wallet
});
results += `\nNFT ${i+1} minted successfully.`;
mintedNFTsCount++;
resultField.value = results;
} catch (error) {
console.log(error);
}
// Add a small delay to avoid hitting rate limits if many NFTs are being minted
await new Promise(resolve => setTimeout(resolve, 500));
}
results += `\n\nAttempted to mint ${nftCount} NFTs. Successfully minted ${mintedNFTsCount} NFTs.`;
results += "\n\nFetching minted NFTs...\n";
let nfts;
try {
nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress,
limit: 400
});
results += JSON.stringify(nfts, null, 2);
while (nfts.result.marker) {
nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress,
limit: 400,
marker: nfts.result.marker
});
results += '\n' + JSON.stringify(nfts, null, 2);
}
} catch (error) {
results += `\nError fetching account NFTs: ${error.message}`;
}
try {
xrpBalanceField.value = (await client.getXrpBalance(wallet.address));
} catch (error) {
results += `\nError fetching XRP balance: ${error.message}`;
}
resultField.value = results;
} catch (error) {
results += `\nAn unexpected error occurred during batch minting: ${error.message}`;
resultField.value = results;
} finally {
if (client && client.isConnected()) {
client.disconnect();
results += '\nDisconnected from XRP Ledger.';
resultField.value = results;
}
}
} // End of batchMint()
// *******************************************************
// **************** Get Batch Tokens *********************
// *******************************************************
async function getBatchNFTs() {
let client; // Declare client here for finally block access
try {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
let net = getNet();
client = new xrpl.Client(net); // Assign client
results = 'Connecting to ' + net + '...';
resultField.value = results;
await client.connect();
results += '\nConnected. Getting NFTs...';
resultField.value = results;
results += "\n\nNFTs:\n";
let nfts;
try {
nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress,
limit: 400
});
results += JSON.stringify(nfts, null, 2);
while (nfts.result.marker) {
nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress,
limit: 400,
marker: nfts.result.marker
});
results += '\n' + JSON.stringify(nfts, null, 2);
}
} catch (error) {
results += `\nError fetching account NFTs: ${error.message}`;
}
resultField.value = results;
} catch (error) {
results += `\nAn unexpected error occurred while getting batch NFTs: ${error.message}`;
resultField.value = results;
} finally {
if (client && client.isConnected()) {
client.disconnect();
results += '\nDisconnected from XRP Ledger.';
resultField.value = results;
}
}
} //End of getBatchNFTs()

View File

@@ -0,0 +1,291 @@
<html>
<head>
<title>Broker NFTs</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src="transaction-support.js"></script>
<script src="mint-nfts.js"></script>
<script src="transfer-nfts.js"></script>
<script src="broker-nfts.js"></script>
</head>
<body>
<h1>Broker NFTs</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label
for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
<td rowspan="4" align="center">
<p>
<img id="nftImage"
src="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"
width="150" height="150">
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td>
</td>
<td align="right">
<span class="tooltip" tooltip-data="URL to the stored NFT.">
<label for="nftURLfield">NFT URL</label>
</span>
</td>
<td>
<input type="text" id="nftURLfield" size="40"
placeholder="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"></input>
<br />
<p id="error-message"></p>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT ID code, used to identify the token after it's minted.">
<label for="nftIdField">NFT ID</label>
</span>
</td>
<td>
<input type="text" id="nftIdField" size="40"></input>
</td>
<td align="center" valign="top">
<button type="button" onClick="getNFTs()">Get NFTs</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Account address of the Owner of an NFT offered to sell or buy.">
<label for="nftOwnerField">NFT Owner Address</label>
</span>
</td>
<td>
<input type="text" id="nftOwnerField" size="40"></input>
</td>
<td colspan="2" align="center" valign="top">
<button type="button" onClick="getOffers()" width="40">Get Offers</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Index of the sell offer to broker.">
<label for="nftSellOfferIndexField">Sell Offer Index</label>
</span>
</td>
<td>
<input type="text" id="nftSellOfferIndexField" size="40"></input>
<br>
</td>
<td align="middle" valign="top" colspan="2">
<button type="button" onClick="brokerSale()">Broker Sale</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Index of the buy offer to broker.">
<label for="nftBuyOfferIndexField">Buy Offer Index</label>
</span>
</td>
<td>
<input type="text" id="nftBuyOfferIndexField" size="40"></input>
<br>
</td>
<td align="middle" valign="top" colspan="2">
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Fee collected by the broker account when the brokered deal is complete.">
<label for="brokerFeeField">Broker Fee</label>
</span>
</td>
<td>
<input type="text" id="brokerFeeField" size="40"></input>
</td>
</tr>
<tr valign="top">
<td colspan="2">
<p align="left">
<textarea id="resultField" cols="75" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br />
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const imageURLInput = document.getElementById('nftURLfield'); // Correct ID to nftURLfield
const displayImage = document.getElementById('nftImage');
const loadButton = document.getElementById('showNFTbutton');
const errorMessage = document.getElementById('error-message');
if (imageURLInput) {
imageURLInput.addEventListener('change', () => {
const newURL = imageURLInput.value;
displayImage.src = ''; // Clear previous image
errorMessage.style.display = 'none';
try {
new URL(newURL);
} catch (_) {
errorMessage.textContent = 'Invalid URL. Please enter a valid URL, including "https://" or "http://".';
errorMessage.style.display = 'block';
return;
}
displayImage.onload = () => {
// Image loaded. You might add a console log here, or update UI.
console.log(`Image loaded from: ${newURL}`);
};
displayImage.onerror = () => {
errorMessage.textContent = 'Error loading image from the provided URL.';
errorMessage.style.display = 'block';
displayImage.src = ''; // Clear the image on error
};
displayImage.src = newURL; // Load the image
});
}
});
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function () {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,44 @@
// *******************************************************
// ******************* Broker Sale ***********************
// *******************************************************
async function brokerSale() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
const net = getNet();
const client = new xrpl.Client(net);
let results = `\n=== Connected. Brokering the sale. ===`;
resultField.value = results;
try {
await client.connect();
// Prepare transaction -------------------------------------------------------
const brokerTx = {
"TransactionType": "NFTokenAcceptOffer",
"Account": wallet.classicAddress,
"NFTokenSellOffer": nftSellOfferIndexField.value,
"NFTokenBuyOffer": nftBuyOfferIndexField.value,
"NFTokenBrokerFee": brokerFeeField.value
}
console.log(JSON.stringify(brokerTx, null, 2));
// Submit transaction --------------------------------------------------------
const tx = await client.submitAndWait(brokerTx, { wallet: wallet })
// Check transaction results -------------------------------------------------
results += "\n\nTransaction result:\n" +
JSON.stringify(tx.result.meta.TransactionResult, null, 2)
results += "\nBalance changes:\n" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
resultField.value += results
} catch (error) {
console.error("Error in broker sale:", error);
results = `\n\n=== Error in broker sale: ${error.message} ===`; // User friendly
resultField.value += results;
}
finally {
if (client && client.isConnected()) {
await client.disconnect();
}
}
}// End of brokerSale()

View File

@@ -0,0 +1,313 @@
<html>
<head>
<title>Mint NFTs</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src='transaction-support.js'></script>
<script src='mint-nfts.js'></script>
</head>
<body>
<h1>Mint NFTs</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label
for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
<td rowspan="4" align="center">
<p>
<img id="nftImage"
src="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"
width="150" height="150">
</td>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT configuration flags.">
<label for="flagsField">Flags</label>
</span>
</td>
<td>
<input type="text" id="flagsField" size="40"></input>
</td>
<td align="right">
<span class="tooltip" tooltip-data="URL to the stored NFT.">
<label for="nftURLfield">NFT URL</label>
</span>&nbsp;&nbsp;
<input type="text" id="nftURLfield" size="30"
value="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Percentage of sale price collected by the issuer when the NFT is sold. Enter a value from 0 to 50000, where 1000=1%.">
<label for="transferFeeField">Transfer Fee</label>
</span>
<p id="error-message"></p>
</td>
<td>
<input type="text" id="transferFeeField" size="40"></input>
</td>
<td>
<button type="button" onClick="mintNFT()">Mint NFT</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT Taxon. Integer value used to identify NFTs minted in a series or collection. This value is required. Set it to 0 if you have no use for it.">
<label for="nftTaxonField">NFT Taxon</label>
</span>
</td>
<td>
<input type="text" id="nftTaxonField" size="40" value="0"></input>
</td>
<td>
<button type="button" onClick="getNFTs()">Get NFTs</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Currency for the offer.">
<label for="currencyField">Currency</label>
</span>
</td>
<td>
<input type="text" id="currencyField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="burnNFT()">Burn NFT</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuer of the currency used.">
<label for="issuerField">Issuer</label>
</span>
</td>
<td>
<input type="text" id="issuerField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of currency to send. If XRP, you can enter 1 per XRP: the amount is converted to drops for you.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where XRP is sent.">
<label for="destinationField">Destination</label>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Number of days the offer is valid.">
<label for="expirationField">Expiration (days)</label>
</span>
</td>
<td>
<input type="text" id="expirationField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT ID, used to transfer or burn the NFT after it is created.">
<label for="nftIdField">NFT ID</label>
</span>
</td>
<td>
<input type="text" id="nftIdField" size="40"></input>
</td>
</tr>
<tr>
<td colspan="2">
<p align="left">
<textarea id="resultField" cols="75" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br />
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const imageURLInput = document.getElementById('nftURLfield'); // Correct ID to nftURLfield
const displayImage = document.getElementById('nftImage');
const errorMessage = document.getElementById('error-message');
if (imageURLInput) {
imageURLInput.addEventListener('change', () => {
const newURL = imageURLInput.value;
displayImage.src = ''; // Clear previous image
errorMessage.style.display = 'none';
try {
new URL(newURL);
} catch (_) {
errorMessage.textContent = 'Invalid URL. Please enter a valid URL, including "https://" or "http://".';
errorMessage.style.display = 'block';
return;
}
displayImage.onload = () => {
// Image loaded. You might add a console log here, or update UI.
console.log(`Image loaded from: ${newURL}`);
};
displayImage.onerror = () => {
errorMessage.textContent = 'Error loading image from the provided URL.';
errorMessage.style.display = 'block';
displayImage.src = ''; // Clear the image on error
};
displayImage.src = newURL; // Load the image
});
}
});
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function () {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,141 @@
// *******************************************************
// ********************** Mint NFT ***********************
// *******************************************************
async function mintNFT() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
const net = getNet();
const client = new xrpl.Client(net);
let results = `\n=== Connected. Minting NFT ===`;
resultField.value = results;
try {
await client.connect();
// Prepare transaction parameters
const transactionParams = {
TransactionType: "NFTokenMint",
Account: wallet.classicAddress,
URI: xrpl.convertStringToHex(nftURLfield.value),
Flags: parseInt(flagsField.value, 10), // Parse to integer
TransferFee: parseInt(transferFeeField.value, 10), // Parse to integer
NFTokenTaxon: parseInt(nftTaxonField.value, 10), // Parse to integer
};
// Add optional fields
if (amountField.value) {
transactionParams.Amount = configureAmount(amountField.value);
}
if (expirationField.value) {
transactionParams.Expiration = configureExpiration(expirationField.value);
}
if (destinationField.value) {
transactionParams.Destination = destinationField.value;
}
console.log("Mint NFT Transaction Parameters:", transactionParams); // Log before submitting
// Submit transaction
const tx = await client.submitAndWait(transactionParams, { wallet });
// Get minted NFTs
const nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress,
});
// Report results
results += `\n\n=== Transaction result: ${tx.result.meta.TransactionResult} ===`;
results += `\n\n=== NFTs: ${JSON.stringify(nfts, null, 2)} ===`;
results += `\n\n=== XRP Balance: ${await client.getXrpBalance(wallet.address)} ===`; // Await here
resultField.value = results;
} catch (error) {
console.error("Error minting NFT:", error);
results += `\n\n=== Error minting NFT: ${error.message} ===`; // Use error.message
resultField.value = results;
} finally {
if (client && client.isConnected()) { // Check if connected before disconnecting
await client.disconnect();
}
}
} // End of mintToken()
// *******************************************************
// ******************** Get NFTs *************************
// *******************************************************
async function getNFTs() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
const net = getNet();
const client = new xrpl.Client(net);
let results = '\n=== Connected. Getting NFTs. ===';
resultField.value = results;
try {
await client.connect();
const nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress,
});
results = '\n=== NFTs:\n ' + JSON.stringify(nfts, null, 2) + ' ==='; // Consistent formatting
resultField.value = results;
} catch (error) {
console.error("Error getting NFTs:", error);
results += `\n\n=== Error getting NFTs: ${error.message} ===`; // User-friendly
resultField.value = results;
} finally {
if (client && client.isConnected()) {
await client.disconnect();
}
}
} // End of getNFTs()
// *******************************************************
// ********************** Burn NFT ***********************
// *******************************************************
async function burnNFT() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
const net = getNet();
const client = new xrpl.Client(net);
let results = '\n=== Connected. Burning NFT. ===';
resultField.value = results;
try {
await client.connect();
// Prepare transaction
const transactionBlob = {
TransactionType: "NFTokenBurn",
Account: wallet.classicAddress,
NFTokenID: nftIdField.value,
};
console.log("Burn NFT Transaction Parameters:", transactionBlob); // Log before submit
// Submit transaction and wait for the results
const tx = await client.submitAndWait(transactionBlob, { wallet });
const nfts = await client.request({ // Get nfts after burning.
method: "account_nfts",
account: wallet.classicAddress,
});
results = `\n=== Transaction result: ${tx.result.meta.TransactionResult} ===`;
results += '\n\n=== Balance changes: ' +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2) + ' ===';
results += '\n\n=== NFTs: \n' + JSON.stringify(nfts, null, 2) + ' ===';
resultField.value = results;
xrpBalanceField.value = (await client.getXrpBalance(wallet.address)); // Await
} catch (error) {
console.error("Error burning NFT:", error);
results = `\n\n=== Error burning NFT: ${error.message} ===`; // User friendly
resultField.value = results;
} finally {
if (client && client.isConnected()) {
await client.disconnect();
}
}
} // End of burnNFT()

View File

@@ -0,0 +1,153 @@
body {
font-family: "Inter", sans-serif;
padding: 20px;
background: #abe2ff;
}
h1 {
font-weight: bold;
}
td {
padding-left: 25px;
vertical-align: top;
}
input,
button {
padding: 6px;
margin-bottom: 8px;
border: none
}
input:read-only {
background-color:rgb(11, 96, 132);
color:white;
border: 0;
}
button {
font-weight: bold;
font-family: "Work Sans", sans-serif;
background-color: #006aff;
-webkit-text-fill-color: white;
width: 144px;
}
button:hover {
background-color: #0555c5;
cursor: pointer;
}
label {
font-weight: bold;
}
td {
vertical-align: middle;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 30px;
height: 16px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 4px;
bottom: 2px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
/* Rounded sliders */
.slider.round {
border-radius: 17px;
}
.slider.round:before {
border-radius: 50%;
}
.tooltip {
position: relative;
border-bottom: 1px dotted black;
}
.tooltip:before {
content: attr(tooltip-data);
position: absolute;
width: 250px;
background-color: #006aff;
color: #fff;
text-align: center;
padding: 15px;
line-height: 1.1;
border-radius: 5px;
z-index: 1;
opacity: 0;
transition: opacity .5s;
bottom: 125%;
left: 50%;
margin-left: -60px;
font-size: 0.70em;
visibility: hidden;
}
.tooltip:after {
content: "";
position: absolute;
bottom: 75%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
opacity: 0;
transition: opacity .5s;
border-color: #000 transparent transparent transparent;
visibility: hidden;
}
.tooltip:hover:before,
.tooltip:hover:after {
opacity: 1;
visibility: visible;
}

View File

@@ -0,0 +1,36 @@
// ****************************************
// ********* Configure Amount *************
// ****************************************
function configureAmount() {
let amount = '';
if (currencyField.value === "XRP" || currencyField.value === "") {
if (amountField.value !== '') {
amount = amountField.value; // XRP amount should be a string of drops
} else {
amount = undefined;
}
} else if (currencyField.value !== "") {
amount = {
currency: currencyField.value,
issuer: issuerField.value,
value: amountField.value,
};
} else {
amount = undefined; // Or handle the case where no currency is provided
}
return amount;
}
// ****************************************
// ********* Configure Expiration *********
// ****************************************
function configureExpiration() {
let expiration = ""
var days = expirationField.value
let d = new Date()
d.setDate(d.getDate() + parseInt(days))
expiration = xrpl.isoTimeToRippleTime(d)
return expiration
} // End of configureExpiration()

View File

@@ -0,0 +1,328 @@
<html>
<head>
<title>Transfer NFTs</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src="account-support.js"></script>
<script src="transaction-support.js"></script>
<!-- <script src='send-xrp.js'></script> -->
<script src="transfer-nfts.js"></script>
<script src="mint-nfts.js"></script>
</head>
<body>
<h1>Transfer NFTs</h1>
<form id="theForm">
<span class="tooltip" tooltip-data="Choose the XRPL host server for your account.">
Choose your ledger instance:
</span>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
&nbsp;&nbsp;
<input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br /><br />
<table>
<tr>
<td>
<button type="button" onClick="getNewAccount1()">Get New Account 1</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed1()">Get Account 1 From Seed</button>
</td>
<td>
<button type="button" onClick="getNewAccount2()">Get New Account 2</button>
</td>
<td>
<button type="button" onClick="getAccountFromSeed2()">Get Account 2 From Seed</button>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account."><label
for="account1name">Account 1 Name</label>
</span>
</td>
<td>
<input type="text" id="account1name" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Arbitrary human-readable name for the account.">
<label for="account2name">Account 2 Name</label>
</span>
</td>
<td>
<input type="text" id="account2name" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account1address">Account 1 Address</label>
</span>
</td>
<td>
<input type="text" id="account1address" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Identifying address for the account.">
<label for="account2address">Account 2 Address</label>
</span>
</td>
<td>
<input type="text" id="account2address" size="40"></input>
</td>
</tr>
<tr>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account1seed">Account 1 Seed</label>
</span>
</td>
<td>
<input type="text" id="account1seed" size="40"></input>
</td>
<td>
<span class="tooltip" tooltip-data="Seed for deriving public and private keys for the account.">
<label for="account2seed">Account 2 Seed</label>
</span>
</td>
<td>
<input type="text" id="account2seed" size="40"></input>
</td>
</tr>
</table>
<hr />
<table>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Name of the currently selected account.">
<label for="accountNameField">Account Name</label>
</span>
</td>
<td>
<input type="text" id="accountNameField" size="40" readonly></input>
<input type="radio" id="account1" name="accounts" value="account1">
<label for="account1">Account 1</label>
</td>
<td rowspan="4" align="center">
<p>
<img id="nftImage"
src="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"
width="150" height="150">
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Address of the currently selected account.">
<label for="accountAddressField">Account Address</label>
</span>
</td>
<td>
<input type="text" id="accountAddressField" size="40" readonly></input>
<input type="radio" id="account2" name="accounts" value="account2">
<label for="account2">Account 2</label>
</td>
</tr>
<tr valign="top">
<td align="right">
<span class="tooltip" tooltip-data="Seed of the currently selected account.">
<label for="accountSeedField">Account Seed</label>
</span>
</td>
<td>
<input type="text" id="accountSeedField" size="40" readonly></input>
<br>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="XRP balance for the currently selected account.">
<label for="xrpBalanceField">XRP Balance</label>
</span>
</td>
<td>
<input type="text" id="xrpBalanceField" size="40" readonly></input>
</td>
</tr>
<tr>
<td>
</td>
<td>
</td>
<td>
<span class="tooltip" tooltip-data="URL to the stored NFT.">
<label for="nftURLfield">NFT URL</label>
</span>
<input type="text" id="nftURLfield" size="30"
placeholder="https://ipfs.io/ipfs/bafybeigjro2d2tc43bgv7e4sxqg7f5jga7kjizbk7nnmmyhmq35dtz6deq"></input>
<br />
<p id="error-message"></p>
</td>
</tr>
<tr>
<td align="right" >
<span class="tooltip" tooltip-data="Currency for the offer.">
<label for="currencyField">Currency</label>
</span>
</td>
<td>
<input type="text" id="currencyField" size="40"></input>
<br>
</td>
<td align="center" valign="top">
<button type="button" onClick="getNFTs()">Get NFTs</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Issuer of the currency used.">
<label for="issuerField">Issuer</label>
</span>
</td>
<td>
<input type="text" id="issuerField" size="40"></input>
<br>
</td>
<td>
<button type="button" onClick="createSellOffer()">Create Sell Offer</button>&nbsp;&nbsp;
<button type="button" onClick="createBuyOffer()">Create Buy Offer</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Amount of XRP to send.">
<label for="amountField">Amount</label>
</span>
</td>
<td>
<input type="text" id="amountField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="acceptSellOffer()">Accept Sell Offer</button>&nbsp;&nbsp;
<button type="button" onClick="acceptBuyOffer()">Accept Buy Offer</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Destination account address where XRP is sent.">
<label for="destinationField">Destination</label>
</span>
</td>
<td>
<input type="text" id="destinationField" size="40"></input>
<br>
</td>
<td align="left" valign="top">
<button type="button" onClick="getOffers()" width="40">Get Offers</button>&nbsp;&nbsp;
<button type="button" onClick="cancelOffer()">Cancel Offer</button>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Number of days the offer is valid.">
<label for="expirationField">Expiration (days)</label>
</span>
</td>
<td>
<input type="text" id="expirationField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT ID code, used to identify the token after it's minted.">
<label for="nftIdField">NFT ID</label>
</span>
</td>
<td>
<input type="text" id="nftIdField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="NFT Offer ID code, used to identify an offer to sell or buy an NFT.">
<label for="nftOfferIdField">NFT Offer ID</label>
</span>
</td>
<td>
<input type="text" id="nftOfferIdField" size="40"></input>
</td>
</tr>
<tr>
<td align="right">
<span class="tooltip" tooltip-data="Account address of the Owner of an NFT offered to sell or buy.">
<label for="nftOwnerField">NFT Owner Address</label>
</span>
</td>
<td>
<input type="text" id="nftOwnerField" size="40"></input>
</td>
</tr>
<tr valign="top">
<td colspan="2">
<p align="left">
<textarea id="resultField" cols="75" rows="20"></textarea>
</p>
</td>
<td align="left" valign="top">
<button type="button" onClick="gatherAccountInfo()">Gather Account Info</button><br />
<button type="button" onClick="distributeAccountInfo()">Distribute Account Info</button>
</td>
</tr>
</table>
</form>
</body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const imageURLInput = document.getElementById('nftURLfield'); // Correct ID to nftURLfield
const displayImage = document.getElementById('nftImage');
const loadButton = document.getElementById('showNFTbutton');
const errorMessage = document.getElementById('error-message');
if (imageURLInput) {
imageURLInput.addEventListener('change', () => {
const newURL = imageURLInput.value;
displayImage.src = ''; // Clear previous image
errorMessage.style.display = 'none';
try {
new URL(newURL);
} catch (_) {
errorMessage.textContent = 'Invalid URL. Please enter a valid URL, including "https://" or "http://".';
errorMessage.style.display = 'block';
return;
}
displayImage.onload = () => {
// Image loaded. You might add a console log here, or update UI.
console.log(`Image loaded from: ${newURL}`);
};
displayImage.onerror = () => {
errorMessage.textContent = 'Error loading image from the provided URL.';
errorMessage.style.display = 'block';
displayImage.src = ''; // Clear the image on error
};
displayImage.src = newURL; // Load the image
});
}
});
const radioButtons = document.querySelectorAll('input[type="radio"]');
radioButtons.forEach(radio => {
radio.addEventListener('change', function () {
if (this.value === 'account1') {
populate1()
} else if (this.value === 'account2') {
populate2()
}
});
});
</script>
</html>

View File

@@ -0,0 +1,339 @@
// *********************************************************
// *************** Create Sell Offer ***********************
// *********************************************************
async function createSellOffer() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
let results = '\nCreating sell offer...';
resultField.value = results;
try {
const client = new xrpl.Client(getNet());
await client.connect();
try {
const destination = destinationField.value || undefined;
const expiration = expirationField.value ? configureExpiration() : undefined;
const transactionJson = {
TransactionType: "NFTokenCreateOffer",
Account: wallet.classicAddress,
NFTokenID: nftIdField.value,
Flags: 1,
};
const amount = configureAmount();
if (amount) { // Only add Amount if it's defined
transactionJson.Amount = amount;
} else {
console.warn("Amount is undefined. Sell offer might be invalid.");
results += "\nWarning: Amount is undefined. Sell offer might be invalid, unless you plan to give away the NFT.";
resultField.value = results;
}
if (expiration) {
transactionJson.Expiration = expiration;
}
if (destination) {
transactionJson.Destination = destination;
}
const tx = await client.submitAndWait(transactionJson, { wallet });
results += `\nSell offer created successfully!\nTransaction Hash: ${tx.result.hash}\nEngine Result: ${tx.result.engine_result}`;
resultField.value = results;
} finally {
client.disconnect();
}
} catch (error) {
console.error("Error creating sell offer:", error);
results = `\nError: ${error.message || error}`;
resultField.value = results;
}
}// End of createSellOffer()
// *******************************************************
// ***************** Create Buy Offer ********************
// *******************************************************
async function createBuyOffer() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
let net = getNet();
const client = new xrpl.Client(net);
await client.connect();
let results = '\n=== Connected. Creating buy offer. ===';
resultField.value = results;
try {
// Use the external configureAmount() function
let amount = configureAmount();
// Use the external configureExpiration() function
let expiration = configureExpiration(); // This will return a number or an empty string from the original logic
let transactionJson = {
"TransactionType": "NFTokenCreateOffer",
"Account": wallet.classicAddress,
"Owner": nftOwnerField.value,
"NFTokenID": nftIdField.value,
"Flags": 0, // Ensure no tfSellNFToken flag for a buy offer
};
// Only add Amount if it's defined (not undefined or an empty string)
if (amount !== undefined && amount !== '') {
transactionJson.Amount = amount;
} else {
results += "\nError: Amount field is required for a buy offer.";
resultField.value = results;
client.disconnect();
return;
}
if (destinationField.value !== '') {
transactionJson.Destination = destinationField.value;
}
// Only add Expiration if it's not an empty string
if (expiration > 0) {
transactionJson.Expiration = expiration;
}
const tx = await client.submitAndWait(transactionJson, { wallet: wallet });
results += "\n\n=== Sell Offers ===\n";
let nftSellOffers;
try {
nftSellOffers = await client.request({
method: "nft_sell_offers",
nft_id: nftIdField.value
});
} catch (err) {
nftSellOffers = "=== No sell offers. ===";
}
results += JSON.stringify(nftSellOffers, null, 2);
results += "\n\n=== Buy Offers ===\n";
let nftBuyOffers;
try {
nftBuyOffers = await client.request({
method: "nft_buy_offers",
nft_id: nftIdField.value
});
results += JSON.stringify(nftBuyOffers, null, 2);
} catch (err) {
results += "=== No buy offers. ===";
}
// Check transaction results -------------------------------------------------
results += "\n\n=== Transaction result:\n" +
JSON.stringify(tx.result.meta.TransactionResult, null, 2);
results += "\n\n=== Balance changes:\n" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2);
resultField.value = results;
} catch (error) {
console.error('Error creating buy offer:', error);
results += "\n\n=== Error: " + error;
resultField.value = results;
} finally {
client.disconnect();
}
}// End of createBuyOffer()
// *******************************************************
// ******************** Cancel Offer *********************
// *******************************************************
async function cancelOffer() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = "\n=== Connected. Cancelling offer. ==="
resultField.value = results
const tokenOfferIDs = [nftOfferIdField.value]
// Prepare transaction -------------------------------------------------------
const transactionJson = {
"TransactionType": "NFTokenCancelOffer",
"Account": wallet.classicAddress,
"NFTokenOffers": tokenOfferIDs
}
// Submit transaction --------------------------------------------------------
const tx = await client.submitAndWait(transactionJson, { wallet })
results = "\n\n=== Sell Offers===\n"
let nftSellOffers
try {
nftSellOffers = await client.request({
method: "nft_sell_offers",
nft_id: nftIdField.value
})
} catch (err) {
nftSellOffers = '=== No sell offers. ===\n'
}
results += JSON.stringify(nftSellOffers, null, 2)
results += "\n\n=== Buy Offers ===\n"
let nftBuyOffers
try {
nftBuyOffers = await client.request({
method: "nft_buy_offers",
nft_id: nftIdField.value
})
} catch (err) {
nftBuyOffers = '=== No buy offers. ==='
}
results += JSON.stringify(nftBuyOffers, null, 2)
resultField.value += results
// Check transaction results -------------------------------------------------
results = "\n=== Transaction result:\n" +
JSON.stringify(tx.result.meta.TransactionResult, null, 2)
results += "\n\n=== Balance changes:\n" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
resultField.value += results
client.disconnect() // End of cancelOffer()
}
// *******************************************************
// ******************** Get Offers ***********************
// *******************************************************
async function getOffers() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
let net = getNet()
const client = new xrpl.Client(net)
await client.connect()
let results = '\nConnected. Getting offers...'
resultField.value = results
// --- Sell Offers ---
results += '\n\n=== Sell Offers ===\n'
let nftSellOffers
try {
nftSellOffers = await client.request({
method: "nft_sell_offers",
nft_id: nftIdField.value
})
} catch (err) {
nftSellOffers = 'No sell offers found for this NFT ID.'
}
results += JSON.stringify(nftSellOffers, null, 2)
resultField.value = results
// --- Buy Offers ---
results = '\n\n=== Buy Offers ===\n'
let nftBuyOffers
try {
nftBuyOffers = await client.request({
method: "nft_buy_offers",
nft_id: nftIdField.value
})
} catch (err) {
// Log the actual error for debugging
nftBuyOffers = 'No buy offers found for this NFT ID.' // More descriptive
}
results += JSON.stringify(nftBuyOffers, null, 2) // Append the JSON string
resultField.value += results // Update the display with buy offers
client.disconnect()
}// End of getOffers()
// *******************************************************
// ****************** Accept Sell Offer ******************
// *******************************************************
async function acceptSellOffer() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
let net = getNet()
const client = new xrpl.Client(net)
try {
await client.connect()
let results = '\n=== Connected. Accepting sell offer. ===\n\n'
resultField.value = results
// Prepare transaction -------------------------------------------------------
const transactionJson = {
"TransactionType": "NFTokenAcceptOffer",
"Account": wallet.classicAddress,
"NFTokenSellOffer": nftOfferIdField.value,
}
// Submit transaction --------------------------------------------------------
const tx = await client.submitAndWait(transactionJson, { wallet: wallet })
const nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress
})
// Check transaction results -------------------------------------------------
xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
results += '=== Transaction result:\n'
results += JSON.stringify(tx.result.meta.TransactionResult, null, 2)
results += '\n=== Balance changes:'
results += JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2)
results += JSON.stringify(nfts, null, 2)
resultField.value += results
} catch (error) {
console.error('Error accepting sell offer:', error)
resultField.value = `Error: ${error.message || error}`
} finally {
client.disconnect()
}
}// End of acceptSellOffer()
// *******************************************************
// ******************* Accept Buy Offer ******************
// *******************************************************
async function acceptBuyOffer() {
const wallet = xrpl.Wallet.fromSeed(accountSeedField.value);
let net = getNet();
const client = new xrpl.Client(net);
let results = '\n=== Connected. Accepting buy offer. ==='; // Declare results locally
try {
await client.connect();
resultField.value = results; // Update UI after connection
// Prepare transaction -------------------------------------------------------
const transactionJson = {
"TransactionType": "NFTokenAcceptOffer",
"Account": wallet.classicAddress,
"NFTokenBuyOffer": nftOfferIdField.value
};
// Submit transaction --------------------------------------------------------
const tx = await client.submitAndWait(transactionJson, { wallet: wallet });
const nfts = await client.request({
method: "account_nfts",
account: wallet.classicAddress
});
results += JSON.stringify(nfts, null, 2);
resultField.value = results;
// Check transaction results -------------------------------------------------
results += "\n\nTransaction result:\n" +
JSON.stringify(tx.result.meta.TransactionResult, null, 2);
results += "\nBalance changes:\n" +
JSON.stringify(xrpl.getBalanceChanges(tx.result.meta), null, 2);
xrpBalanceField.value = (await client.getXrpBalance(wallet.address));
resultField.value = results;
} catch (error) {
console.error('Error in acceptBuyOffer:', error); // Log the full error
results = `\n=== Error accepting buy offer: ${error.message || 'Unknown error'} ===`;
resultField.value = results;
} finally {
if (client && client.isConnected()) {
client.disconnect();
}
}
} // End of acceptBuyOffer()

View File

@@ -27,8 +27,8 @@ async function mintToken() {
// ----------------------------------------------------- Submit signed blob
const tx = await client.submitAndWait(transactionJson, { wallet: standby_wallet} )
const nfts = await client.request({
method: "account_nfts",
account: standby_wallet.classicAddress
"method": "account_nfts",
"account": standby_wallet.classicAddress
})
// ------------------------------------------------------- Report results

View File

@@ -37,7 +37,11 @@ const args = parseArgs(process.argv.slice(2), {
function _pretty(message, color) {
if (!args.raw) {
console.log(color, message)
if (color) {
console.log(color,message)
} else {
console.log(message)
}
}
}
@@ -60,4 +64,4 @@ if (args.json) {
} else {
rawJson = fs.readFileSync(args.filename, 'utf8')
main(rawJson, args.verbose)
}
}

View File

@@ -7,10 +7,9 @@
"big-integer": "^1.6.52",
"buffer": "^6.0.3",
"decimal.js": "^10.4.3",
"fs": "^0.0.1-security",
"minimist": "^1.2.7",
"ripple-address-codec": "^5.0.0",
"xrpl": "^4.0.0"
"xrpl": "^4.2.5"
},
"main": "index.js",
"scripts": {

View File

@@ -6,7 +6,7 @@ you can use to verify the behavior of the transaction serialization code.
For example (starting from the `tx-serialization/js/` dir above this one):
```bash
$ node index.js -f test-cases/tx2.json | \
$ node index.js -rf test-cases/tx2.json | \
diff - test-cases/tx2-binary.txt
```
@@ -46,7 +46,7 @@ CDC63E1DEE7FE3744630440220143759437C04F7B61F012563AFE90D8DAFC46E86035E1D965A9CED
For a friendlier display, you could pipe the output of the serializer to a file and use a visual tool like [Meld](http://meldmerge.org/) that shows intra-line differences:
```bash
$ cat test-cases/tx1.json | sed -e 's/"Fee": "10"/"Fee": "100"/' | node index.js --stdin > /tmp/tx1-modified.txt && meld /tmp/tx1-modified.txt test-cases/tx1-binary.txt
$ cat test-cases/tx1.json | sed -e 's/"Fee": "10"/"Fee": "100"/' | node index.js --raw --stdin > /tmp/tx1-modified.txt && meld /tmp/tx1-modified.txt test-cases/tx1-binary.txt
```
![Meld screenshot showing the `0A` / `64` difference](meld-example.png)

View File

@@ -92,7 +92,7 @@ class TxSerializer {
_decodeAddress(address) {
const decoded = codec.decodeChecked(address)
if (decoded[0] === 0 && decoded.length === 21) {
return decoded.slice(1)
return Buffer.from(decoded.slice(1))
}
throw new Error("Not an AccountID!")
@@ -161,7 +161,7 @@ class TxSerializer {
const byte2 = this.uint8ToBytes(typeCode)
const byte3 = this.uint8ToBytes(fieldCode)
return "" + byte1 + byte2 + byte3 //TODO: bytes is python function
return "" + byte1 + byte2 + byte3
}
}
@@ -681,9 +681,8 @@ class TxSerializer {
fieldsAsBytes.push(fieldBytes)
}
}
return fieldsAsBytes.join('')
}
}
module.exports = TxSerializer
module.exports = TxSerializer

View File

@@ -11,9 +11,9 @@ author: Rome Reginelli
---
# Dev Portal Adds rippled APIs
Today, the [Ripple Dev Portal](https://developers.ripple.com/) gets a big boost of content and usability. The new additions to our development portal include thorough and tested documentation of all the public API methods for our core server software, rippled, alongside a host of improvements in styling and formatting, as well as new introductory material to give you direction in navigating the sea of Ripple technology.
Today, the Ripple Dev Portal gets a big boost of content and usability. The new additions to our development portal include thorough and tested documentation of all the public API methods for our core server software, rippled, alongside a host of improvements in styling and formatting, as well as new introductory material to give you direction in navigating the sea of Ripple technology.
This update brings very crucial content into the fold of documentation that's thorough, complete, and software-tested. Today, you can access [full specs and usage information for all 20+ public methods in the rippled WebSocket API](https://developers.ripple.com/rippled-api.html).
This update brings very crucial content into the fold of documentation that's thorough, complete, and software-tested. Today, you can access [full specs and usage information for all 20+ public methods in the rippled WebSocket API](/docs/references/http-websocket-apis/public-api-methods).
<!-- BREAK -->

View File

@@ -8,8 +8,10 @@ markdown:
---
# Do You Have What It Takes to Be a Gateway?
We're proud to announce the first release of [our new Gateway Guide](https://developers.ripple.com/become-an-xrp-ledger-gateway.html), a comprehensive manual to operating a gateway in the Ripple network. Whether you're trying to understand [how a gateway makes revenue](https://developers.ripple.com/become-an-xrp-ledger-gateway.html#fees-and-revenue-sources), or how to use the [authorized accounts](https://developers.ripple.com/become-an-xrp-ledger-gateway.html#authorized-trust-lines) feature, or even just [what a warm wallet is](https://developers.ripple.com/issuing-and-operational-addresses.html), the gateway guide has you covered.
We're proud to announce the first release of our new Gateway Guide, a comprehensive manual to operating a gateway in the Ripple network. Whether you're trying to understand how a gateway makes revenue, or how to use the authorized accounts feature, or even just what a warm wallet is, the gateway guide has you covered.
The guide comes with step-by-step, diagrammed explanations of typical gateway operations, a hefty [list of precautions](https://developers.ripple.com/become-an-xrp-ledger-gateway.html#precautions) to make your gateway safer, and concrete examples of all the API calls you need to perform in order to get your gateway accounts set up and secure.
The guide comes with step-by-step, diagrammed explanations of typical gateway operations, a hefty list of precautions to make your gateway safer, and concrete examples of all the API calls you need to perform in order to get your gateway accounts set up and secure.
We're proud of all the work we've done to make the business of running a gateway easier, but there's still more work to do. If you have any questions, comments, or ideas, please send feedback to <developers@ripple.com> - or post it on our forums. We'd love to hear from you!
> _Editor's note, 2025: This guide is now obsolete and removed. For the nearest modern equivalent, see the [Stablecoin Issuer use case](/docs/use-cases/tokenization/stablecoin-issuer)._

View File

@@ -20,7 +20,7 @@ The Data API also includes a lot of new capabilities, including:
- a new endpoint to show account balance changes
- new metrics in transaction stats
We are making these changes quickly and are focusing our resources on building out and testing new endpoints. Documentation for the Data API will soon be available on [ripple.com/build](http://ripple.com/build). The API will live at [data.ripple.com](http://data.ripple.com). In the meantime, you can look through the [Data API in GitHub](https://github.com/ripple/rippled-historical-database/blob/develop/README.md).
We are making these changes quickly and are focusing our resources on building out and testing new endpoints. Documentation for the Data API will soon be available on `ripple.com/build`. The API will live at `data.ripple.com`. In the meantime, you can look through the [Data API in GitHub](https://github.com/ripple/rippled-historical-database/blob/develop/README.md).
Because we are pulling all of the data endpoints under one API, we are shutting down some of our underutilized endpoints that are relying on infrastructure we are not moving forward with. The first shutdown will be CouchDB on August 19th, which we used early on for Ripple Charts. We are replacing some of the endpoints that hit CouchDB in the Data API, but other, less frequently used calls are being removed. In the next few months, we will also be shutting down the Ripple Charts API and replacing aspects of that by expanding the Data API. The Historical Database API version one will live in parallel to the Data API as we make this transition. It will be deprecated by the end of the year.

View File

@@ -12,7 +12,7 @@ markdown:
At Ripple Labs, our goal is to expand the size and diversity of the Ripple consensus network by enabling people to easily run rippled validators and understand how those validators perform. We aim to create a network where validating participants are well known and respected by gathering and publicizing identity information of validators in addition to performance statistics.
Today, we are excited to announce the launch of the Ripple Validator Registry at [xrpcharts.ripple.com/#/validators](https://xrpcharts.ripple.com/#/validators). The Validator Registry gathers and publishes data for all network validators, enabling rippled operators to determine which validators to trust. An [http-based API](https://data.ripple.com/v2/network/validators) is also available for dynamically constructing rippled configurations.
Today, we are excited to announce the launch of the Ripple Validator Registry at `xrpcharts.ripple.com/#/validators`. The Validator Registry gathers and publishes data for all network validators, enabling rippled operators to determine which validators to trust. An http-based API is also available for dynamically constructing rippled configurations. _[2025 Update: See <https://livenet.xrpl.org/network/validators> for the modern equivalent of the validator registry.]_
## Build a UNL
@@ -25,6 +25,6 @@ The Validator Registry provides several metrics for each validator based on upti
- disagreement - the percentage of ledgers validated by the validator that did not pass consensus
### Identity
Network participants are unlikely to trust validators without knowing who is operating them. To address this concern, validator operators can associate their validator with a web domain that they operate by following the steps on the [Ripple Dev Portal](https://ripple.com/build/rippled-apis/rippled-setup/#domain-verification). The Validator Registry verifies these domains and lists them with the validators.
Network participants are unlikely to trust validators without knowing who is operating them. To address this concern, validator operators can associate their validator with a web domain that they operate by following the steps for [Domain Verification](https://xrpl.org/docs/references/xrp-ledger-toml#domain-verification). The Validator Registry verifies these domains and lists them with the validators.
As the consensus network continues to grow, we hope the Validator Registry plays a key role in decentralizing and strengthening the network through open data.

View File

@@ -12,14 +12,14 @@ markdown:
The Data team is proud to announce the release of the [Ripple Data API v2.2](https://github.com/ripple/rippled-historical-database/releases/tag/v2.2.0)! This release includes lots of new features, including a total of 15 new methods, improvements in data quality, and documentation.
One of the biggest changes in the new version is the incorporation of data relating to the Ripple network itself. This includes expanded information on [validator reports](https://ripple.com/build/data-api-v2/#get-daily-validator-reports), [network topology](https://ripple.com/build/data-api-v2/#get-topology), and the [XRP transaction costs](https://ripple.com/build/data-api-v2/#get-transaction-costs) currently being paid to the network. You can interact with all of the new methods using our [Data API Tool](https://ripple.com/build/data-api-tool/).
One of the biggest changes in the new version is the incorporation of data relating to the Ripple network itself. This includes expanded information on validator reports, network topology, and the XRP transaction costs currently being paid to the network. You can interact with all of the new methods using our Data API Tool.
Also part of the new release is a method to calculate the [distribution of XRP](https://ripple.com/build/data-api-v2/#get-xrp-distribution) from Ripple (the company) to others, along with the total amount of XRP in existence. The [XRP Portal](https://ripple.com/xrp-portal/) is already using the new method to report the most recent totals automatically.
Also part of the new release is a method to calculate the distribution of XRP from Ripple (the company) to others, along with the total amount of XRP in existence. The XRP Portal is already using the new method to report the most recent totals automatically.
For more information, check out the following resources:
* [Data API Docs in the Ripple Developer Center](https://ripple.com/build/data-api-v2/)
* [Data API source code](https://github.com/ripple/rippled-historical-database)
* [Data visualizations on Ripple Charts](https://xrpcharts.ripple.com/)
_\[Update: Data API docs and Data visualizations on Ripple Charts are no longer available. The links have been removed.\]_
We look forward to seeing what you developers can do with all this data!

Some files were not shown because too many files have changed in this diff Show More